angularangular-httpclienthttpcontextangular-http-interceptorsangular-httpclient-interceptors

HttpContextToken always false while using HttpInterceptorFn


I am implementing a loading spinner that runs for all my http requests via an HttpInterceptorFn using this blog post as a guide: https://blog.angular-university.io/angular-loading-indicator/

loading.interceptor.ts

export const loadingInterceptor: HttpInterceptorFn = (req, next) => {
  const loadingSpinnerService = inject(LoadingSpinnerService);
  console.log('SkipLoading: ', req.context.get(SkipLoading));
  if (req.context.get(SkipLoading)) {
    return next(req);
  }
  loadingSpinnerService.setIsLoading(true);
  return next(req).pipe(
    finalize(() => {
      loadingSpinnerService.setIsLoading(false);
    }),
  );
};

HttpContextToken exported from the loading-spinner.service.ts

export const SkipLoading = new HttpContextToken<boolean>(() => false);

refreshToken API call where I wish to skip the spinner

refreshToken() {
    return this.http.post<TokenResponse>(
      this.apiUrl + '/Token/refresh/' + this.siteUserId$.value?.toString(),
      { context: new HttpContext().set(SkipLoading, true) },
    );
  }

Using console.log() I am noticing that my SkipLoading token is always false. Is there some difference in the implementation when using HttpInterceptorFn rather than HttpInterceptor class?

EDIT: After changing the API type to GET the context token evaluates to true as expected. But I must still be doing something wrong as I need this functionality for POST requests as well.


Solution

  • For post the syntax is given in the HttpClient - Angular.dev as:

    post(url: string, body: any, options: { headers?: HttpHeaders | 
    { [header: string]: string | string[]; } | undefined; context?: HttpContext | undefined; 
    observe?: "body" | undefined; params?: HttpParams | { ...; } | undefined; 
    reportProgress?: boolean | undefined; responseType: "arraybuffer"; withCredentials?: boolean | undefined; 
    transferCache?: boolean ...): Observable<ArrayBuffer>;
    

    Notice that the second argument is the body of the post request, so the context should be passed in an object as the third argument.

      refreshToken() {
        return this.http.post<TokenResponse>(
          this.apiUrl + '/Token/refresh/' + this.siteUserId$.value?.toString(),
          null, { context: new HttpContext().set(SkipLoading, true) },
        );
      }