0

I have an angular aplications, which shows articles on first page. I don't want that api call is executed twice, first on the server and once on the client side, so I used transfer state to check if api was already called. If I use REST API everything works fine and api call is executed on server only but when I add graphql with apollo this doesen't seems to work.

async ngOnInit() {
let myTransferStateKey = makeStateKey<any>('myDatas');

if (this.transferState.hasKey(myTransferStateKey)) {
  console.log('HomeComponent ngOnInit hasKey');
  this.transferState.get(myTransferStateKey, [])
  this.transferState.remove(myTransferStateKey);
} else {
  console.log('HomeComponent ngOnInit noKey');
  
  this.posts = (await this.graphql.query(this.home_query)) as {
    capital: string
    currency: string
    languages: []
    name: string
    native: string
  }[] 

  this.transferState.set(myTransferStateKey, this.posts) 
  
}

}

Redberry57
  • 36
  • 4

1 Answers1

0

If you use Apollo consider using the method used in their docs. Remember to add in the configuration ssrMode and ssrForceFetchDelay for it to work properly. It is also important to set the API server url correctly, as they mention in Best practices. Sample:

import { APOLLO_OPTIONS } from 'apollo-angular';
import { HttpLink } from 'apollo-angular/http';
import { HttpClientModule } from '@angular/common/http';
import { InjectionToken, NgModule } from '@angular/core';
import { BrowserModule, makeStateKey, TransferState } from '@angular/platform-browser';
import { InMemoryCache } from '@apollo/client/core';
 
const APOLLO_CACHE = new InjectionToken<InMemoryCache>('apollo-cache');
const STATE_KEY = makeStateKey<any>('apollo.state');
 
@NgModule({
  imports: [
    // ...
    BrowserModule,
    HttpClientModule,
  ],
  providers: [
    {
      provide: APOLLO_CACHE,
      useValue: new InMemoryCache(),
    },
    {
      provide: APOLLO_OPTIONS,
      useFactory(httpLink: HttpLink, cache: InMemoryCache, transferState: TransferState) {
        const isBrowser = transferState.hasKey<any>(STATE_KEY);
 
        if (isBrowser) {
          const state = transferState.get<any>(STATE_KEY, null);
          cache.restore(state);
        } else {
          transferState.onSerialize(STATE_KEY, () => {
            return cache.extract();
          });
          // Reset cache after extraction to avoid sharing between requests
          cache.reset();
        }

        return {
          link: httpLink.create({ '/graphql', withCredentials: true }),
          cache,
          ssrMode: true,
          ssrForceFetchDelay: 100,
        };
      },
      deps: [HttpLink, APOLLO_CACHE, TransferState],
    },
  ],
  // ...
})
class AppModule {}
Diego
  • 709
  • 7
  • 18