Browse Source

fix(admin-ui): Fix cyclic dependency in http interceptor

Michael Bromley 7 years ago
parent
commit
868a6ea605

+ 1 - 6
admin-ui/src/app/core/providers/i18n/i18n.service.ts

@@ -7,12 +7,7 @@ import { LanguageCode } from '../../../data/types/gql-generated-types';
 @Injectable()
 export class I18nService {
     constructor(private ngxTranslate: TranslateService) {
-        // For some unknown reason, calling `setDefaultLang(getDefaultLanguage())`
-        // produces a stack overflow in some cases, wheras assigning an intermediate
-        // var does not. ¯\_(ツ)_/¯
-        const defaultLang = getDefaultLanguage();
-        // TODO: this constructor is called many times on bootstrap. Investigate why and fix.
-        ngxTranslate.setDefaultLang(defaultLang);
+        ngxTranslate.setDefaultLang(getDefaultLanguage());
     }
 
     /**

+ 16 - 7
admin-ui/src/app/data/providers/interceptor.ts

@@ -1,4 +1,3 @@
-/** Pass untouched request through to the next request handler. */
 import {
     HttpErrorResponse,
     HttpEvent,
@@ -7,9 +6,9 @@ import {
     HttpRequest,
     HttpResponse,
 } from '@angular/common/http';
-import { Injectable } from '@angular/core';
-import { Observable, throwError } from 'rxjs';
-import { catchError, tap } from 'rxjs/operators';
+import { Injectable, Injector } from '@angular/core';
+import { Observable } from 'rxjs';
+import { tap } from 'rxjs/operators';
 
 import { NotificationService } from '../../core/providers/notification/notification.service';
 
@@ -21,7 +20,7 @@ import { DataService } from './data.service';
  */
 @Injectable()
 export class DefaultInterceptor implements HttpInterceptor {
-    constructor(private dataService: DataService, private notification: NotificationService) {}
+    constructor(private dataService: DataService, private injector: Injector) {}
 
     intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
         this.dataService.client.startRequest().subscribe();
@@ -35,7 +34,7 @@ export class DefaultInterceptor implements HttpInterceptor {
                 },
                 err => {
                     if (err instanceof HttpErrorResponse) {
-                        this.notification.error(err.message);
+                        this.displayErrorNotification(err.message);
                         this.dataService.client.completeRequest().subscribe();
                     }
                 },
@@ -51,7 +50,17 @@ export class DefaultInterceptor implements HttpInterceptor {
         const graqhQLErrors = response.body.errors;
         if (graqhQLErrors && Array.isArray(graqhQLErrors)) {
             const message = graqhQLErrors.map(err => err.message).join('\n');
-            this.notification.error(message);
+            this.displayErrorNotification(message);
         }
     }
+
+    /**
+     * We need to lazily inject the NotificationService since it depends on the I18nService which
+     * eventually depends on the HttpClient (used to load messages from json files). If we were to
+     * directly inject NotificationService into the constructor, we get a cyclic dependency.
+     */
+    private displayErrorNotification(message: string): void {
+        const notificationService = this.injector.get(NotificationService);
+        notificationService.error(message);
+    }
 }