Angular Uncaught Error: не удается разрешить все параметры для ErrorInterceptor - PullRequest
0 голосов
/ 11 ноября 2019

Я получаю следующее сообщение: «Неопознанная ошибка: невозможно разрешить все параметры для ErrorInterceptor: (?)» При попытке внедрить AuthenticationService.

error.interceptor.ts

import { Injectable } from '@angular/core';
import ...

import { AuthenticationService } from '@/_services';

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
    constructor(private authenticationService: AuthenticationService) {}

    intercept(request: HttpRequest<any>, next: HttpHandler): 
    Observable<HttpEvent<any>> {
        return next.handle(request).pipe(catchError(err => {
            if (err.status === 401) {
                // auto logout if 401 response returned from api
                this.authenticationService.logout();
                location.reload(true);
            }

            const error = err.error.message || err.statusText;
            return throwError(error);
        }))
    }
}

authentication.service.ts

import { Injectable } from '@angular/core';
import ...

@Injectable({ providedIn: 'root' })
export class AuthenticationService {
private currentUserSubject: BehaviorSubject<User>;
public currentUser: Observable<User>;

constructor(private http: HttpClient) {
    this.currentUserSubject = new BehaviorSubject<User>(JSON.parse(localStorage.getItem('currentUser')));
    this.currentUser = this.currentUserSubject.asObservable();
}

public get currentUserValue(): User {
    return this.currentUserSubject.value;
}

login(username, password) {
    ...
}

logout() {
    ...
}
}

app.module.ts содержит:

providers: [
    { provide: HTTP_INTERCEPTORS, useClass: ErrorInterceptor, multi: true }
]

Я использую Angular 8. Полный код ошибки:

Uncaught Error: Can't resolve all parameters for ErrorInterceptor: (?).
at syntaxError (compiler.js:2687)
at CompileMetadataResolver._getDependenciesMetadata (compiler.js:21355)
at CompileMetadataResolver._getTypeMetadata (compiler.js:21248)
at CompileMetadataResolver._getInjectableTypeMetadata (compiler.js:21470)
at CompileMetadataResolver.getProviderMetadata (compiler.js:21479)
at eval (compiler.js:21417)
at Array.forEach (<anonymous>)
at CompileMetadataResolver._getProvidersMetadata (compiler.js:21377)
at CompileMetadataResolver.getNgModuleMetadata (compiler.js:21096)
at JitCompiler._loadModules (compiler.js:27143)

1 Ответ

1 голос
/ 11 ноября 2019

Проблема в круговой зависимости. AuthenticationService нужно HttpClient, HttpClient нужно Interceptors, ErrorInterceptor нужно AuthenticationService.

Чтобы решить эту проблему, вам нужно разделить AuthenticationService на два слоя - один для храненияданные аутентификации и один для связи API.

class AuthenticationStore {
   storeData(authData) {}
   getData(): AuthData {}
   clearData() {}

Скажем, у вас есть AuthenticationStore. Тогда ErrorInterceptor будет использовать AuthenticationStore вместо AuthenticationService.

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
    constructor(private authenticationStore: AuthenticationStore) {}

    intercept(request: HttpRequest<any>, next: HttpHandler): 
    Observable<HttpEvent<any>> {
        return next.handle(request).pipe(catchError(err => {
            if (err.status === 401) {
                // auto logout if 401 response returned from api
                this.authenticationStore.clearData();
                location.reload(true);
            }

            const error = err.error.message || err.statusText;
            return throwError(error);
        }))
    }
}

Или вы можете использовать инжектор, это немного более грязное решение.

@Injectable()
export class ErrorInterceptor implements HttpInterceptor {
    constructor(private injector: Injector) {}

    intercept(request: HttpRequest<any>, next: HttpHandler): 
    Observable<HttpEvent<any>> {
        return next.handle(request).pipe(catchError(err => {
            if (err.status === 401) {
                // auto logout if 401 response returned from api
                const authenticationService = this.injector.get(AuthenticationService);
                authenticationService.logout();
                location.reload(true);
            }

            const error = err.error.message || err.statusText;
            return throwError(error);
        }))
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...