Browse Source

fix(admin-ui): Switch to 'cache-and-network' fetchPolicy

Fixes #9
Michael Bromley 7 years ago
parent
commit
b81945d7bd

+ 2 - 1
admin-ui/src/app/data/data.module.ts

@@ -3,6 +3,7 @@ import { APP_INITIALIZER, NgModule } from '@angular/core';
 import { Apollo, APOLLO_OPTIONS, ApolloModule } from 'apollo-angular';
 import { HttpLink, HttpLinkModule } from 'apollo-angular-link-http';
 import { InMemoryCache } from 'apollo-cache-inmemory';
+import { ApolloClientOptions } from 'apollo-client';
 import { ApolloLink } from 'apollo-link';
 import { withClientState } from 'apollo-link-state';
 
@@ -31,7 +32,7 @@ const stateLink = withClientState({
     defaults: clientDefaults,
 });
 
-export function createApollo(httpLink: HttpLink) {
+export function createApollo(httpLink: HttpLink): ApolloClientOptions<any> {
     return {
         link: ApolloLink.from([
             stateLink,

+ 30 - 3
admin-ui/src/app/data/providers/base-data.service.ts

@@ -1,6 +1,9 @@
 import { HttpClient } from '@angular/common/http';
 import { Injectable } from '@angular/core';
 import { Apollo } from 'apollo-angular';
+import { DataProxy } from 'apollo-cache';
+import { FetchPolicy } from 'apollo-client';
+import { ExecutionResult } from 'apollo-link';
 import { DocumentNode } from 'graphql/language/ast';
 import { Observable } from 'rxjs';
 import { map } from 'rxjs/operators';
@@ -9,6 +12,15 @@ import { API_URL } from '../../app.config';
 import { LocalStorageService } from '../../core/providers/local-storage/local-storage.service';
 import { QueryResult } from '../types/query-result';
 
+/**
+ * Make the MutationUpdaterFn type-safe until this issue is resolved: https://github.com/apollographql/apollo-link/issues/616
+ */
+export type TypedFetchResult<T = Record<string, any>> = ExecutionResult & {
+    context?: T;
+    data: T;
+};
+export type TypedMutationUpdateFn<T> = (proxy: DataProxy, mutationResult: TypedFetchResult<T>) => void;
+
 @Injectable()
 export class BaseDataService {
     constructor(
@@ -20,7 +32,11 @@ export class BaseDataService {
     /**
      * Performs a GraphQL watch query
      */
-    query<T, V = Record<string, any>>(query: DocumentNode, variables?: V): QueryResult<T, V> {
+    query<T, V = Record<string, any>>(
+        query: DocumentNode,
+        variables?: V,
+        fetchPolicy: FetchPolicy = 'cache-and-network',
+    ): QueryResult<T, V> {
         const queryRef = this.apollo.watchQuery<T, V>({
             query,
             variables,
@@ -29,6 +45,7 @@ export class BaseDataService {
                     Authorization: this.getAuthHeader(),
                 },
             },
+            fetchPolicy,
         });
         return new QueryResult<T, any>(queryRef);
     }
@@ -36,8 +53,18 @@ export class BaseDataService {
     /**
      * Performs a GraphQL mutation
      */
-    mutate<T, V = Record<string, any>>(mutation: DocumentNode, variables?: V): Observable<T> {
-        return this.apollo.mutate<T, V>({ mutation, variables }).pipe(map(result => result.data as T));
+    mutate<T, V = Record<string, any>>(
+        mutation: DocumentNode,
+        variables?: V,
+        update?: TypedMutationUpdateFn<T>,
+    ): Observable<T> {
+        return this.apollo
+            .mutate<T, V>({
+                mutation,
+                variables,
+                update: update as any,
+            })
+            .pipe(map(result => result.data as T));
     }
 
     /**

+ 7 - 2
admin-ui/src/app/data/types/query-result.ts

@@ -1,6 +1,7 @@
 import { QueryRef } from 'apollo-angular';
+import { NetworkStatus } from 'apollo-client';
 import { Observable } from 'rxjs';
-import { map, take } from 'rxjs/operators';
+import { filter, map, take } from 'rxjs/operators';
 
 /**
  * This class wraps the Apollo Angular QueryRef object and exposes some getters
@@ -14,6 +15,7 @@ export class QueryResult<T, V = Record<string, any>> {
      */
     get single$(): Observable<T> {
         return this.queryRef.valueChanges.pipe(
+            filter(result => result.networkStatus === NetworkStatus.ready),
             take(1),
             map(result => result.data),
         );
@@ -23,7 +25,10 @@ export class QueryResult<T, V = Record<string, any>> {
      * Returns an Observable which emits until unsubscribed.
      */
     get stream$(): Observable<T> {
-        return this.queryRef.valueChanges.pipe(map(result => result.data));
+        return this.queryRef.valueChanges.pipe(
+            filter(result => result.networkStatus === NetworkStatus.ready),
+            map(result => result.data),
+        );
     }
 
     get ref(): QueryRef<T, V> {