I'm using apollo client for graphql. I set up the client in AppApolloModule that I'm importing in AppModule. I'm making a query in a service which is also imported right in the AppModule. Although the service runs before the AppApolloModule runs and hence apollo is not initialized when the query is made and I get this error
Error: Client has not been defined yet
AppApolloModule
imports ....
export class AppApolloModule {
constructor(
apollo: Apollo,
httpLink: HttpLink,
private userService: UserService
) {
console.log("apollo module")
apollo.create({
link: httpLink.create({ uri: `${environment.apiBase}/graphql?${this.myService.token}`}),
cache: new InMemoryCache()
})
}
}
App Module
import { AppApolloModule } from './app.apollo.module';
import { MyService } from './services/my.service';
export class AppModule {
constructor() {
console.log("app module")
}
}
I don't get the two consoles app module and apollo module, since the service runs first, it doesn't find any initialized apollo app and thus breaks the code.
How can I make apollo run before the service or any services for that matter in an efficient and standard way?
I'm using apollo client for graphql. I set up the client in AppApolloModule that I'm importing in AppModule. I'm making a query in a service which is also imported right in the AppModule. Although the service runs before the AppApolloModule runs and hence apollo is not initialized when the query is made and I get this error
Error: Client has not been defined yet
AppApolloModule
imports ....
export class AppApolloModule {
constructor(
apollo: Apollo,
httpLink: HttpLink,
private userService: UserService
) {
console.log("apollo module")
apollo.create({
link: httpLink.create({ uri: `${environment.apiBase}/graphql?${this.myService.token}`}),
cache: new InMemoryCache()
})
}
}
App Module
import { AppApolloModule } from './app.apollo.module';
import { MyService } from './services/my.service';
export class AppModule {
constructor() {
console.log("app module")
}
}
I don't get the two consoles app module and apollo module, since the service runs first, it doesn't find any initialized apollo app and thus breaks the code.
How can I make apollo run before the service or any services for that matter in an efficient and standard way?
Share Improve this question edited Mar 14, 2018 at 6:11 Manzur Khan asked Mar 13, 2018 at 13:39 Manzur KhanManzur Khan 2,4864 gold badges25 silver badges46 bronze badges 8- Have you tried using app lifecycle OnInit ? try implementing the OnInit interface and bring your code into the ngOnInit method – Mehdi Benmoha Commented Mar 13, 2018 at 13:44
-
Maybe have a look at
APP_INITIALIZER
token – David Commented Mar 13, 2018 at 13:47 - @e.m.b services don't have ngOnInit – Manzur Khan Commented Mar 13, 2018 at 14:04
- I meant move the code in the modules constructor to the ngOnInit in the modules not the services – Mehdi Benmoha Commented Mar 13, 2018 at 15:12
- @e.m.b that won't help either, as contructor function runs first, putting it on ngOnIt will make them load even after more time – Manzur Khan Commented Mar 13, 2018 at 16:44
5 Answers
Reset to default 9This will solve the issue nicely:
import {NgModule} from '@angular/core';
import {HttpClientModule} from '@angular/mon/http';
import {ApolloModule, APOLLO_OPTIONS} from 'apollo-angular';
import {HttpLink, HttpLinkModule} from 'apollo-angular-link-http';
import {InMemoryCache} from 'apollo-cache-inmemory';
export function createApollo(httpLink: HttpLink) {
return {
link: httpLink.create({uri: 'https://api.example./graphql'}),
cache: new InMemoryCache(),
};
}
@NgModule({
imports: [HttpClientModule, ApolloModule, HttpLinkModule],
providers: [
{
provide: APOLLO_OPTIONS,
useFactory: createApollo,
deps: [HttpLink],
},
],
})
class AppModule {}
I have the same issue an the docs from Apollo helped me. Go to 'https://www.apollographql./docs/angular/basics/setup/' or copy this:
import { HttpClientModule } from "@angular/mon/http";
import { ApolloModule, APOLLO_OPTIONS } from "apollo-angular";
import { HttpLinkModule, HttpLink } from "apollo-angular-link-http";
import { InMemoryCache } from "apollo-cache-inmemory";
@NgModule({
imports: [
BrowserModule,
HttpClientModule,
ApolloModule,
HttpLinkModule
],
providers: [{
provide: APOLLO_OPTIONS,
useFactory: (httpLink: HttpLink) => {
return {
cache: new InMemoryCache(),
link: httpLink.create({
uri: "https://o5x5jzoo7z.sse.codesandbox.io/graphql"
})
}
},
deps: [HttpLink]
}],
})
export class AppModule {}
The answer by @wendellmva didn't work for me. What did work was the solution suggested in this repo:
https://github./patricknazar/angular-lazy-loading-apollo-client
which is basically to put Apollo initialization in a separate, shared module, and include it in your main app module with forRoot()
.
What worked for me was deleting the .angular
folder and serving the application again.
Here is how it worked for me with angular +16/17:
app.config.ts
import { ApplicationConfig, importProvidersFrom } from '@angular/core';
import { provideHttpClient } from '@angular/mon/http';
import {
provideRouter,
withComponentInputBinding,
withEnabledBlockingInitialNavigation,
withViewTransitions,
} from '@angular/router';
import { appRoutes } from './app.routes';
import { provideAnimations } from '@angular/platform-browser/animations';
import {
ApolloClientOptions,
ApolloLink,
GraphQLRequest,
InMemoryCache,
} from '@apollo/client/core';
import { APOLLO_OPTIONS, ApolloModule } from 'apollo-angular';
import { HttpLink } from 'apollo-angular/http';
import { setContext } from '@apollo/client/link/context';
import { SECRET, URI, PROPERTY } from './uri-info';
export function createApollo(httpLink: HttpLink): ApolloClientOptions<any> {
const headers = setContext((operation: GraphQLRequest, context) => ({
headers: {
[PROPERTY]: SECRET,
},
}));
return {
link: ApolloLink.from([headers, httpLink.create({ uri: URI })]),
cache: new InMemoryCache(),
};
}
export const appConfig: ApplicationConfig = {
providers: [
provideRouter(
appRoutes,
withEnabledBlockingInitialNavigation(),
withComponentInputBinding(),
withViewTransitions(),
),
provideHttpClient(),
provideAnimations(),
importProvidersFrom(ApolloModule),
{
provide: APOLLO_OPTIONS,
useFactory: createApollo,
deps: [HttpLink],
},
],
};
init-graphQl.ponent.ts
import { Apollo, gql } from 'apollo-angular';
import { Component, OnInit, inject } from '@angular/core';
@Component({
standalone: true,
selector: 'test-init-graphql',
template: `Console log is here`,
})
export class InitGraphQlComponent implements OnInit {
#apollo = inject(Apollo);
ngOnInit(): void {
this.#apollo
.watchQuery({
query: gql`
{
Entity {
firstProperty
secondProperty
}
}
`,
})
.valueChanges.subscribe((result: any) => {
console.log(result);
});
}
}