1

I have the following ApolloServer (v4)

import { MongoDataSource } from 'apollo-datasource-mongodb'

export default class LoaderAsset extends MongoDataSource {
 async getAsset(assetId) {
    return this.findOneById(assetId) // ERROR IS HERE
  }
}

async function startApolloServer(app) {
  const httpServer = http.createServer(app);
  
  const server = new ApolloServer({
    typeDefs,
    resolvers,
    plugins: [ApolloServerPluginDrainHttpServer({ httpServer })]
    
  });

  await server.start();
  app.use(
    '/graphql',
    cors(),
    bodyParser.json(),
    expressMiddleware(server, {
      context: async ({ req }) => {
       return {
        dataSources: {
          loaderAsset: new LoaderAsset(modelAsset),
        }
      }
      },
    }),
  );


  const port = config.get('Port') || 8081;
  await new Promise(resolve => httpServer.listen({ port }, resolve));
}

when I run graphql and send one assetId, everything is working till I get following error:

this.findOneById is not a function By the way (this) has collection and model objects but not any methods.

is it because apollo-datasource-mongodb is not compatible with the new version of apollo server v4?

dataSources in v3 were as follows:

 dataSources: () => ({
    users: new Users(client.db().collection('users'))
    // OR
    // users: new Users(UserModel)
  })

but in the new version dataSources is inside the context Maybe the issue is because of this change.

Mehran Ishanian
  • 369
  • 2
  • 4
  • 13

1 Answers1

0

Credit to: https://github.com/systemkrash on https://github.com/GraphQLGuide/apollo-datasource-mongodb/issues/114

what i did is i override my datasource class so I can call the initialize method inside in the MongoDatasource class. Now it works for me.

import { MongoDataSource } from 'apollo-datasource-mongodb';

class ReceptionDataSource extends MongoDataSource {
  constructor({ collection, cache }) {
    super(collection);
    super.initialize({ context: this.context, cache });
  }

  async getReception(receptionId) {
    return await this.findOneById(receptionId);
  }
}

export default ReceptionDataSource;
then in my context

async function startApolloServer(app) {
  const httpServer = http.createServer(app);
  
  const server = new ApolloServer({
    typeDefs,
    resolvers,
    plugins: [ApolloServerPluginDrainHttpServer({ httpServer })]
    
  });

  await server.start();
  app.use(
    '/graphql',
    cors(),
    bodyParser.json(),
    expressMiddleware(server, {
      context: async ({ req }) => {
      const { cache } = server
       return {
        dataSources: {
          loaderAsset: new ReceptionDataSource({collection: ReceptionModel, cache}),
        }
      }
      },
    }),
  );


  const port = config.get('Port') || 8081;
  await new Promise(resolve => httpServer.listen({ port }, resolve));
}
Mehran Ishanian
  • 369
  • 2
  • 4
  • 13