جاوااسکریپت - نوع 'unknown' قابل انتساب به نوع 'HttpEvent' نیست - تلاش برای ایجاد interceptor HTTP در برنامه Angular


من تلاش کردهام یک چرخنده بارگذاری در برنامه Angular خود ایجاد کنم.

من یک آموزش جالب اینجا پیدا کردم (https://medium.com/swlh/angular-loading-spinner-using-http-interceptor-63c1bb76517b).

همه چیز تا مرحله آخر خوب پیش میرفت، وقتی که باید واقعا تابع انقطاع را ایجاد کنم.

import { Injectable } from '@angular/core';
import {
  HttpRequest,
  HttpHandler,
  HttpEvent,
  HttpInterceptor, HttpResponse
} from '@angular/common/http';
import { Observable } from 'rxjs';
import { catchError, map } from 'rxjs/operators'
import { LoadingService } from './loading.service';

/**
 * This class is for intercepting http requests. When a request starts, we set the loadingSub property
 * in the LoadingService to true. Once the request completes and we have a response, set the loadingSub
 * property to false. If an error occurs while servicing the request, set the loadingSub property to false.
 * @class {HttpRequestInterceptor}
 */
@Injectable()
export class HttpRequestInterceptor implements HttpInterceptor {

    /**
     * 
     * @param _loading 
     */
    constructor(
        private _loading: LoadingService
    ) { }

    /**
    * Called at the start of every HTTP request. This function will try to activate the loading spinner
    * @param request 
    * @param next 
    * @returns 
    */
    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        this._loading.setLoading(true, request.url);
        return next.handle(request)
            .pipe(catchError((err) => {
                this._loading.setLoading(false, request.url);
                return err;
            }))
            .pipe(map<HttpEvent<any>, any>((evt: HttpEvent<any>) => {
                if (evt instanceof HttpResponse) {
                    this._loading.setLoading(false, request.url);
                }
                return evt;
            }));
      }
}

لوله اول خوب است.

با این حال، یک خط قرمز بزرگ در سراسر لوله دوم وجود دارد. خطا به شرح زیر است:

نوع آرگومان 'OperatorFunction' قابل انتساب به پارامتر از نوع 'OperatorFunction' نیست. نوع 'unknown' قابل انتساب به نوع 'HttpEvent' نیست. ts(2345)

من این خطا را در VSCode (آبی) و Microsoft VS (بنفش) میبینم، یعنی قطعاً چیزی اشتباه است در کدم نه اینکه IDE من مشکل داشته باشد...

این مقاله در ژوئن ۲۰۲۰ (۴ سال پیش) نوشته شده است، بنابراین ممکن است تغییراتی در نحوه کار observables در Angular رخ داده باشد؟

من حدود یک هفته است که در حال یادگیری Angular هستم و همچنین با TypeScript زیاد آشنا نیستم، بنابراین اگر بعضی از دانشهای پایه را از دست داده باشم، عذرخواهی میکنم، اما قدردان راهنمایی هستم، زیرا مطمئن نیستم چگونه باید ادامه دهم...

اگر کارشناسان Stack Overflow هرگونه پیشنهادی داشته باشند، بسیار قدردانی خواهد شد.

متشکرم!

پاسخ شماره ۱

catchError باید یک observable بازگرداند، بنابراین من از of استفاده میکنم تا خطا را به یک observable تبدیل کنم، این باعث ایجاد خطا در مراحل بعدی روی map میشود.

  intercept(
    request: HttpRequest<any>,
    next: HttpHandler
  ): Observable<HttpEvent<any>> {
    this._loading.setLoading(true, request.url);
    return next.handle(request).pipe(
      catchError((err) => {
        this._loading.setLoading(false, request.url);
        return of(err);
      }),
      map<HttpEvent<any>, HttpEvent<any>>((evt: HttpEvent<any>) => {
        if (evt instanceof HttpResponse) {
          this._loading.setLoading(false, request.url);
        }
        return evt;
      })
    );
  }