最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular - Apollo: Client has not been defined yet - Stack Overflow

programmeradmin8浏览0评论

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
 |  Show 3 more ments

5 Answers 5

Reset to default 9

This 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);
      });
  }
 }

发布评论

评论列表(0)

  1. 暂无评论