Dataloader and Meteor

Id like to start using dataloader with Apollo Server in my Meteor app, but getting the promises not run in fiber error. Is the way to solve this to use wrapasync or is there a cleaner solution? Dataloader expects you to return a promise and async/await wasn’t valid.

Is there any simple example code with meteor somewhere online?

So I figured out one way to do it:

const batchGetPlayers = (keys) => new Promise(function(resolve, reject) {
  console.log('batchGetPlayers');
  console.log(keys);
  Players.rawCollection().find({ _id: { $in: keys } }, { fields: playerFields })
    .toArray((err, result) => {
      console.log('result');
      if (err)
        reject(err);
      else
        resolve(result);
    });
});

const playerLoader = new DataLoader(keys => {
  console.log('DataLoader');
  console.log(keys);
  return batchGetPlayers(keys);
});

I don’t know if there are disadvantages to using rawCollection here.

Could you elaborate on that, please?

When I used async/await in place of the promise it was showing me an error message that I had to pass in a promise instead of a function. I’ll try find the exact error message later. I followed your article to use rawCollection to get it working.

1 Like

A year on and struggling with dataloader again. Funny to see a question by myself with a solution.

In any case, had an easier time this time around. For others looking something like this works:

import DataLoader from 'dataloader';
import Leagues from '.';

export const getLeagueDataLoader = () => new DataLoader(loader);

const loader = async _ids => {
  console.log('finding leagues', _ids);
  return Leagues.find({ _id: { $in: _ids } }).fetch();
};

And adding it to the context:

import { createApolloServer } from 'meteor/apollo';

createApolloServer(() => ({
  schema: executableSchema,
  context: userContext => {
    return {
      ...userContext,
      leagueDataLoader: getLeagueDataLoader(),
    };
  },
  tracing: false,
  cacheControl: false,
  // dumpTraffic: true, // for debugging
})

And using it in a resolver:

  myResolver: async (root, { leagueId }, { leagueDataLoader }) => {
    const league = await leagueDataLoader.load(leagueId);

Not running into any must run in fiber issues using this approach.

I’m on Meteor 1.6.1 and what we’re using for Apollo server is a year old. Apollo has progressed a bunch since then, but haven’t upgraded on this project and not sure how much work that would be with Meteor.