import { NgModule } from '@angular/core' ; import { HttpHeaders } from '@angular/common/http' ; import { ApolloModule , Apollo , APOLLO_OPTIONS } from 'apollo-angular' ; import { HttpLinkModule , HttpLink } from 'apollo-angular-link-http' ; import { InMemoryCache } from 'apollo-cache-inmemory' ; import { ApolloLink } from 'apollo-link' ; import { setContext } from 'apollo-link-context' ; import { onError } from 'apollo-link-error' ; import { NgForage } from 'ngforage' ; import { environment } from '@env' ; const uri = environment . apiUrl ; export function createApollo ( httpLink , ngForage ) { const http = httpLink . create ( { uri } ) ; let token ; const withToken = setContext ( async ( ) => { if ( token ) { return token ; } token = await ngForage . getItem ( 'TOKEN_DATA' ) ; } ) ; const resetToken = onError ( ( { networkError } ) => { if ( networkError && networkError [ 'statusCode' ] === 401 ) { token = '' ; } } ) ; const authFlowLink = withToken . concat ( resetToken ) ; const authMiddleware = new ApolloLink ( ( operation , forward ) => { operation . setContext ( { headers : new HttpHeaders ( ) . set ( 'Authorization' , `Bearer ${ token }` ) } ) ; return forward ( operation ) ; } ) ; const afterwareLink = new ApolloLink ( ( operation , forward ) => { return forward ( operation ) . map ( response => { const { response : { headers } } = operation . getContext ( ) ; return response ; } ) ; } ) ; const errorLink = onError ( ( { graphQLErrors , networkError } ) => { if ( graphQLErrors ) { graphQLErrors . map ( ( { message , locations , path } ) => console . log ( `[GraphQL error]: Message: ${ message }, Location: ${ locations }, Path: ${ path }` ) ) ; } if ( networkError ) { console . log ( `[Network error]:` , networkError ) ; } } ) ; return { link : ApolloLink . from ( [ authFlowLink , authMiddleware , afterwareLink , errorLink , http ] ) , cache : new InMemoryCache ( ) , } ; } @ NgModule ( { exports : [ ApolloModule , HttpLinkModule ] , providers : [ { provide : APOLLO_OPTIONS , useFactory : createApollo , deps : [ HttpLink , NgForage ] , } , ] , } ) export class GraphQLModule { constructor ( private apollo , private httpLink ) { apollo . createNamed ( 'upload' , { cache : new InMemoryCache ( ) , link : httpLink . create ( { uri : 'https://upyun.api.ibenchu.pw/graphql' } ) } ) ; } }