2017-08-13 15 views
0

私はプロジェクトに取り組んでいますが、すべてうまくいきます...(下記の例のように)APIに何かをリクエストすると、明らかに1つのリクエストしか送信されません:インターセプタはAPIで2回の呼び出しを行います

this.httpClient.get<MyInterface>('my_api').subscribe(data => this.items = data); 

しかし、私は新しいのHttpClientにインターセプタを利用したかったので、私は例を検索するために始めたと私はthisを発見しました。

私はポストのようにすべてのものを定義しました:

進捗-interceptor.ts

@Injectable() 
export class ProgressInterceptor implements HttpInterceptor { 

    progress$: Observable<number | null>; 
    private progressSubject: Subject<number | null>; 

    constructor() { 
    this.progressSubject = new ReplaySubject<number | null>(1); 
    this.progress$ = this.progressSubject.asObservable(); 
    } 

    intercept<T>(req: HttpRequest<T>, next: HttpHandler): Observable<HttpEvent<T>> { 
    const reportingRequest = req.clone({ reportProgress: true }); 
    const handle = next.handle(reportingRequest); 

    handle.subscribe((event: HttpEvent<T>) => { 
     switch (event.type) { 
     case HttpEventType.Sent: 
      this.progressSubject.next(undefined); 
      break; 

     case HttpEventType.DownloadProgress: 
     case HttpEventType.UploadProgress: 
      if (event.total) { 
      this.progressSubject.next(Math.round((event.loaded/event.total) * 100)); 
      } 
      break; 

     case HttpEventType.Response: 
      this.progressSubject.next(100); 
      break; 

     default: 
     break; 
     } 
    }); 

    return handle; 
    } 
} 

進捗-component.ts

export class ProgressComponent implements OnInit { 

    progressPercentage$: Observable<number>; 

    @Input() color: ProgressBarColor = 'primary'; 

    @ViewChild(MdProgressBar) private progressBar: MdProgressBar; 

    constructor(private interceptor: ProgressInterceptor) { } 

    ngOnInit(): void { 
    this.progressPercentage$ = this.interceptor.progress$ 
     .map(progress => { 
      if (isNil(progress)) { 
      this.setMode('indeterminate'); 

      return 0; 
      } else { 
      this.setMode('determinate'); 

      return progress; 
      } 
     }); 
    } 

    private setMode(mode: ProgressBarMode) { 
    this.progressBar.mode = mode; 
    } 
} 

アプリ.module.ts

const interceptor = new ProgressInterceptor(); 

@NgModule({ 
    // ... 
    providers: [ 
    { provide: ProgressInterceptor, useValue: interceptor }, 
    { provide: HTTP_INTERCEPTORS, useValue: interceptor, multi: true } 
    ] 
}) 

問題は次のとおりです。このインターセプタでは、リクエストを実行するとAPIが2回ヒットします。どうして?私はそれがProgressInterceptorintercept()内部ためsubscribeだ疑い。

この問題を解決するにはどうすればよいですか?

+0

注意を。 – jonrsharpe

答えて

2

あなたの推測が正しいか、インターセプター内のハンドルに加入することで、あなたは再び観測可能なチェーンをトリガーするため、再びAPI呼び出しをトリガーしています。

適切な演算子は.do(...)see the docs)です。チェイン内部で何が起きているかを観察したいが、その中の何かを操作するつもりはないからです。

それは次のようなものになります。誰かがこの問題を指摘記事にコメントし、私は修正案でそれを更新したことを

intercept<T>(req: HttpRequest<T>, next: HttpHandler): Observable<HttpEvent<T>> { 
    const reportingRequest = req.clone({ reportProgress: true }); 
    return next.handle(reportingRequest) 
      .do((event: HttpEvent<T>) => { 
       switch (event.type) { 
        case HttpEventType.Sent: 
        this.progressSubject.next(undefined); 
        break; 

        case HttpEventType.DownloadProgress: 
        case HttpEventType.UploadProgress: 
        if (event.total) { 
         this.progressSubject.next(Math.round((event.loaded/event.total) * 100)); 
        } 
        break; 

        case HttpEventType.Response: 
        this.progressSubject.next(100); 
        break; 

        default: 
        break; 
       } 
      }); 
} 
+0

ありがとうございました:) –

+0

もう1つのことを教えてください。実際には、次のエラーが表示されます。* "エラーでエラーが発生しました。シンボル値を静的に解決しました。関数 'ProgressInterceptor'を呼び出しています..." *。あなたはそれを解決する方法を知っていますか?私はこの行 'const interceptor = new ProgressInterceptor();'のためにこのエラーが発生していると思いますが、これを削除して動作させる方法がわかりません...削除して 'useClass'に直接入れてください'ProgressInterceptorのプロバイダがありません。 'を取得します。ありがとう。あなたは 'プロバイダを書き込む –

+0

いずれか:[{提供する:HTTP_INTERCEPTORS、useValue:ProgressInterceptor、マルチ:真}]'または 'プロバイダ:[ProgressInterceptorは、{提供する:HTTP_INTERCEPTORS、useExisting:ProgressInterceptor、マルチ:真}]を'。インターセプタ上でnewをコールしないでください。 Angularがインスタンス化します。 – PerfectPixel

関連する問題