The loader.load() function must be called with a value,but got: undefined

Viewed 3876

I am following this graphql tutorial, everything was going ok until I try to use dataloaders.

My server.js is:

const start = async () => {
  const mongo = await connectMongo();

  const buildOptions = async req => {
    const user = await authenticate(req, mongo.Users);
    return {
      context: {
        dataloaders: buildDataloaders(mongo),
        mongo,
        user
      },
      schema
    };
  };
  app.use('/graphql', bodyParser.json(), graphqlExpress(buildOptions));
  app.use(
    '/graphiql',
    graphiqlExpress({
      endpointURL: '/graphql',
      passHeader: `'Authorization': 'bearer token-name@email.com'`
    })
  );
  app.use('/', expressStaticGzip('dist'));
  app.use('/attendance', expressStaticGzip('dist'));
  app.use('/login', expressStaticGzip('dist'));

  spdy.createServer(sslOptions, app).listen(process.env.PORT || 8080, error => {
    if (error) {
      console.error(error);
      return process.exit(1);
    } else {
      console.info(
        `App available at https://localhost:${process.env.PORT || 3000}`
      );
    }
  });
};

My copy and paste dataloaders.js:

const DataLoader = require('dataloader');

async function batchUsers(Users, keys) {
  return await Users.find({ _id: { $in: keys } }).toArray();
}

module.exports = ({ Users }) => ({
  userLoader: new DataLoader(keys => batchUsers(Users, keys), {
    cacheKeyFn: key => key.toString()
  })
});

And my resolvers.js:

export default {
  Query: {
    allLinks: async (root, data, { mongo: { Links } }) =>
      Links.find({}).toArray()
  },
  Mutation: {
    createLink: async (root, data, { mongo: { Links }, user }) => {
      const newLink = Object.assign({ postedById: user && user._id }, data);
      const response = await Links.insert(newLink);
      return Object.assign({ id: response.insertedIds[0] }, newLink);
    },
    createUser: async (root, data, { mongo: { Users } }) => {
      const newUser = {
        name: data.name,
        email: data.authProvider.email.email,
        password: data.authProvider.email.password
      };
      const response = await Users.insert(newUser);
      return Object.assign({ id: response.insertedIds[0] }, newUser);
    },
    signinUser: async (root, data, { mongo: { Users } }) => {
      const user = await Users.findOne({ email: data.email.email });
      if (data.email.password === user.password) {
        return { token: `token-${user.email}`, user };
      }
    }
  },

  Link: {
    id: root => root._id || root.id,
    postedBy: async ({ postedById }, data, { dataloaders: { userLoader } }) => {
      return await userLoader.load(postedById);
    }
  },
  User: {
    id: root => root._id || root.id
  }
};

When I try get my allLinks I got the error:

TypeError: The loader.load() function must be called with a value,but got: undefined.

Can anyone help me?

1 Answers
Related