2017-08-12 22 views
5

Tôi đã cố gắng tạo một HttpInterceptor để thêm một số tiêu đề để ủy quyền cho mọi http xảy ra. Tôi cần lấy các tiêu đề từ một dịch vụ có tên là AuthService. Đây là đoạn mã dưới đây:Lỗi Injector "Lỗi phân tích cú pháp của nhà cung cấp: Không thể khởi tạo phụ thuộc tuần hoàn!"

Interceptor:

import { Injectable } from '@angular/core'; 
import { HttpEvent, HttpInterceptor, HttpHandler, HttpRequest } from '@angular/common/http'; 
import { AuthService } from './auth.service'; 

@Injectable() 
export class AuthInterceptor implements HttpInterceptor { 
    constructor(private auth: AuthService) { } 
} 

AuthService:

import { HttpClient } from '@angular/common/http'; 
import { Injectable } from '@angular/core'; 

@Injectable() 
export class AuthService { 
    constructor(private http: HttpClient) { } 
} 

AppModule:

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

tôi nhận được lỗi sau:

Error: Provider parse errors: Cannot instantiate cyclic dependency! InjectionToken_HTTP_INTERCEPTORS ("[ERROR ->]"): in NgModule AppModule in ./[email protected]:-1

Tôi đã kiểm tra các câu trả lời trước nhưng tôi không hiểu nơi phát hiện sự phụ thuộc chu kỳ. Những gì tôi đang cố gắng làm được mô tả ở đây: https://angular.io/guide/http#setting-new-headers

Trả lời

7

Nhìn này GitHub Discussion (Issue #18224)

Là một workaround bạn có thể sử dụng Injector bằng tay và tiêm dịch vụ có liên quan bên trong intercept phương pháp: https://github.com/angular/angular/issues/18224#issuecomment-316957213

I resolved simply not setting authService in constructor but getting in the intercept function.

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { 
    // Get the auth header from the service. 
    const auth = this.inj.get(AuthenticationService); 
    const authToken = auth.getAuthorizationToken(); 
    ... 
} 

UPDATE:

Trước kiễu góc 4.3.0 un may mắn thay nó không thể sử dụng Injector bằng tay bên intercept phương pháp:

ERROR Error: Uncaught (in promise): RangeError: Maximum call stack size exceeded

Vì vậy, có thêm một workaround sử dụng rxjs:

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { 
    return Observable.create((observer: any) => { 
     setTimeout(() => { 
      const authService = this.injector.get(AuthenticationService) 
      observer.next(authService.getAuthorizationHeader()) 
      observer.complete() 
     }) 
    }) 
     .mergeMap((Authorization: string) => { 
      let authReq = req 

      if (Authorization) { 
       authReq = req.clone({ 
        setHeaders: { 
         Authorization 
        } 
       }) 
      } 

      return next.handle(authReq) 
     }) 
} 
+0

Câu trả lời rất hay và rõ ràng, cảm ơn rất nhiều! :) – dave0688

2

Xóa AuthService khỏi danh sách nhà cung cấp vì nó được nhập vào Bộ chặn do đó sự phụ thuộc theo chu kỳ.

+2

AuthService được sử dụng ở nhiều nơi trên ứng dụng của tôi và tôi cần những ví dụ tương tự mọi nơi. Bất kỳ lựa chọn nào? – itsundefined

+0

Tôi nghĩ rằng tôi đã khắc phục sự cố nhưng có vẻ ngu ngốc ... Tôi đã tách authService thành hai. Trong một tập tin tôi có tất cả các biến và trên tất cả các yêu cầu http khác. Bằng cách này tôi chỉ yêu cầu các biến trên Interceptor của tôi loại bỏ sự phụ thuộc chu kỳ. Đây có phải là một mô hình chống hoặc tôi nên giữ nó? Anyways cảm ơn thời gian của bạn. – itsundefined

+0

@itsUndefined Bạn đã chia lớp dịch vụ thành hai loại như thế nào? nó giống như hai lớp riêng biệt xuất phát từ lớp dịch vụ cơ sở? –

Các vấn đề liên quan