Browse Source

fix(admin-ui): Use Angular HttpClient for API calls

Relates to #19
Michael Bromley 7 years ago
parent
commit
482dabc026

+ 11 - 3
admin-ui/src/app/data/data.module.ts

@@ -18,6 +18,7 @@ import { clientResolvers } from './client-state/client-resolvers';
 import { OmitTypenameLink } from './omit-typename-link';
 import { BaseDataService } from './providers/base-data.service';
 import { DataService } from './providers/data.service';
+import { FetchAdapter } from './providers/fetch-adapter';
 import { DefaultInterceptor } from './providers/interceptor';
 import { loadServerConfigFactory } from './server-config';
 
@@ -34,7 +35,10 @@ const stateLink = withClientState({
     defaults: clientDefaults,
 });
 
-export function createApollo(localStorageService: LocalStorageService): ApolloClientOptions<any> {
+export function createApollo(
+    localStorageService: LocalStorageService,
+    fetchAdapter: FetchAdapter,
+): ApolloClientOptions<any> {
     return {
         link: ApolloLink.from([
             stateLink,
@@ -54,7 +58,10 @@ export function createApollo(localStorageService: LocalStorageService): ApolloCl
                     };
                 }
             }),
-            createUploadLink({ uri: `${API_URL}/${API_PATH}` }),
+            createUploadLink({
+                uri: `${API_URL}/${API_PATH}`,
+                fetch: fetchAdapter.fetch,
+            }),
         ]),
         cache: apolloCache,
     };
@@ -71,10 +78,11 @@ export function createApollo(localStorageService: LocalStorageService): ApolloCl
     providers: [
         BaseDataService,
         DataService,
+        FetchAdapter,
         {
             provide: APOLLO_OPTIONS,
             useFactory: createApollo,
-            deps: [LocalStorageService],
+            deps: [LocalStorageService, FetchAdapter],
         },
         { provide: HTTP_INTERCEPTORS, useClass: DefaultInterceptor, multi: true },
         {

+ 32 - 0
admin-ui/src/app/data/providers/fetch-adapter.ts

@@ -0,0 +1,32 @@
+import { HttpClient } from '@angular/common/http';
+import { Injectable } from '@angular/core';
+
+/**
+ * An adapter that allows the Angular HttpClient to be used as a replacement for the global `fetch` function.
+ * This is used to supply a custom fetch function to the apollo-upload-client whilst also allowing the
+ * use of Angular's http infrastructure such as interceptors.
+ */
+@Injectable()
+export class FetchAdapter {
+    constructor(private httpClient: HttpClient) {}
+
+    fetch = (input: Request | string, init: RequestInit): Promise<Response> => {
+        const url = typeof input === 'string' ? input : input.url;
+        const method = typeof input === 'string' ? (init.method ? init.method : 'GET') : input.method;
+
+        return this.httpClient
+            .request(method, url, {
+                body: init.body,
+                headers: init.headers as any,
+                observe: 'response',
+                responseType: 'json',
+            })
+            .toPromise()
+            .then(result => {
+                return new Response(JSON.stringify(result.body), {
+                    status: result.status,
+                    statusText: result.statusText,
+                });
+            });
+    };
+}