Orbit
Orbit

Reputation: 96

Cannot read property 'fetch' of undefined

I am trying to add a REST datasource to my Apollo Server. I created a class which extends RESTDataSource which contains all the API requests. When trying to call the login method from my GraphQL resolver code the error is thrown

How can I fix this?

I already tried: Binding the login and fetch method in the API class constructor

this.login = this.login.bind(this); this.fetch = this.fetch.bind(this);

calling the login method from the constructor

RESTDataSource class

class API extends RESTDataSource {
        constructor() {
            super();
            this.baseURL = URL;

            this.login = this.login.bind(this);
            this.fetch = this.fetch.bind(this);
            console.log(this.fetch);
            console.log(this.login);

        }
        initialize(config) {
            //config can store different information
            //the current user can be stored in config.context for easy  access
            this.context = config.context;

        }

        async login(username, password) {
            return this.post(`/`, {
                "id": 1
            }, {
                "method": "authenticate"
            }, {
                params: {
                    "user": username,
                    "password": password
                },
                "jsonrpc": "2.0"
            })
        }
    }

Here's the index.js apollo server 'setup' file:

const server = new ApolloServer({
    typeDefs,
    resolvers,
    dataSources: () => {
        return {
            managementDatabase: new ManagementDatabase(),
            API: new API() //was previously imported
        }
    }
});




server.listen().then(({
    url
}) => {
    log(`🚀  Server ready at ${url}`)
})

Resolver file for GraphQL:

Query: {
        lessons: async (_source, _args, {
            dataSources
        }) => {
            const data = await dataSources.webuntisAPI.login(process.env.USER, process.env.PW);
            console.log(data);
            return data;
        }
}

Upvotes: 3

Views: 8272

Answers (3)

Abhay Shiro
Abhay Shiro

Reputation: 3627

I solved this problem by adding http cache from apollo-datasource-rest

import { HTTPCache, RESTDataSource } from "apollo-datasource-rest";

@DataSourceService()
export class MyDataSource extends RESTDataSource {
  constructor() {
    super();

    this.httpCache = new HTTPCache(); // <---- This
    this.baseURL = "http://localhost:8080";
  }

Upvotes: 1

Daya
Daya

Reputation: 119

I am writing this as an answer instead of comment because I don't have enough reps for that. In the tutorial on their official website, this is mentioned. this is mentioned Their tutorial runs fine when cloned and run, but the same isn't working when I implement it with overriding initialize. However, if I don't override it, it works as you've mentioned. Are we doing it wrong? Or their docs need to be updated? Because the incorrect user being present on context is a serious case.

Upvotes: 3

Orbit
Orbit

Reputation: 96

Solved the issue. The problem was the method initalize(config) which is unnecessary in this case. So to fix the issue, just remove the initalize method from your code

Upvotes: 5

Related Questions