Search code examples
angulargraphqllazy-loadingapollo-client

Apollo - Angular : Error: Uncaught (in promise): Error: Client has not been defined yet


I'm trying to use two different apollo clients on my angular app and I get the following error:

Error: Uncaught (in promise): Error: Client has not been defined yet

My graphql.module.ts is setting to handle two different clients by name ('auth' and 'default'):

const authUri = 'http://localhost:4000/graphql/auth';
const defaultUri = 'http://localhost:4000/graphql';

export function createDefaultApollo(httpLink: HttpLink): NamedOptions {
  return {
    default: {
      // name: 'default',
      link: httpLink.create({ uri: defaultUri }),
      cache: new InMemoryCache({
        typePolicies: {
          Quotes: {
            keyFields: ['_id'],
            fields: {
              allQuotes: {
                merge: true,
              },
            },
          },
        },
      }),
    },
    auth: {
      // name: 'auth',
      link: httpLink.create({ uri: authUri }),
      cache: new InMemoryCache(),
    },
  };
}

@NgModule({
  exports: [ApolloModule],
  providers: [
    {
      provide: APOLLO_NAMED_OPTIONS,
      useFactory: createDefaultApollo,
      deps: [HttpLink],
    },
  ],
})
export class GraphQLModule {}

And then, I import the GraphQLModule on the AppModule. I guess that it's some kind of problem related to lazy loading, because the second client (called 'auth') is working perfectly (it's the first module loaded on the application). However, the first client is loaded next with other module and I'm getting the error.

Note: To handle the clients on my services, I'm using:

return this._apollo.use('auth')
           .watchQuery<LoginApiResponse>({
                query,
                variables,
           })

Solution

  • I had the same error. I fixed it by providing both the APOLLO_OPTIONS injection token and the APOLLO_NAMED_OPTIONS injection token in the module.

    Then I just import this module into my AppModule, and it's working.

    It took me forever to figure out, and it's not mentioned anywhere in the documentation, but here's the code:

    import { NgModule } from '@angular/core';
    import { APOLLO_OPTIONS, ApolloModule, APOLLO_NAMED_OPTIONS } from 'apollo-angular';
    import { BrowserModule } from '@angular/platform-browser';
    import { HttpLink } from 'apollo-angular/http';
    import { InMemoryCache } from '@apollo/client/core';
    
    @NgModule({
        exports: [ApolloModule, BrowserModule],
        providers: [
            {
                provide: APOLLO_OPTIONS,
                useFactory: function () {
                    return {
                        link: this.httpLink.create({ uri: 'http://localhost:3333/graphql' }),
                        cache: new InMemoryCache(),
                    };
                },
                deps: [HttpLink],
            },
            {
                provide: APOLLO_NAMED_OPTIONS,
                useFactory: function () {
                    return {
                        productSearch: {
                            link: this.httpLink.create({ uri: 'http://localhost:3334/graphql' }),
                            cache: new InMemoryCache(),
                        },
                    };
                },
                deps: [HttpLink],
            },
        ],
    })
    export class GraphQLModule {}