Remove Loader for particular method which has been added in Interceptor

Viewed 1167

loader-interceptor.ts Loader has been added in Interceptor. In the below upload() function I wouldn't want my loader to get started. The loader should not be applied to that particular method alone.

export class LoaderInterceptorService implements HttpInterceptor {

  constructor(private loaderService: LoaderService) { }
  intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.loaderService.show();
    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.loaderService.show();
    return next.handle(req).pipe(map(event => {
        if (event instanceof HttpResponse) {
           this.loaderService.hide();
        }         
        return event;
    }));
}
  }
}

loader.service.ts This method has 2 methods one to start and stop the spinner.

 export class LoaderService {
      isLoading = new Subject<boolean>();
      constructor() { }
      show() {
    
        this.isLoading.next(true);
      }
      hide() {
        this.isLoading.next(false);
      }
     }

Myuploadservice.ts
In the below method when I call upload() method I don't want my loader to be loaded.

upload(file: File,id) {
    const formdata: FormData = new FormData();
    formdata.append('file', file);
    return this.http.post(`${this.baseURL}/fileupload/${id}`, formdata,{
      reportProgress: true,
      observe: 'events'
    });
  }
3 Answers

Modify your interceptor

export class LoaderInterceptorService implements HttpInterceptor {

    constructor(private loaderService: LoaderService) { }

    intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {

        if(request.url.match(/^\/fileupload/)) {
            return next.handle(req);
        }

        this.loaderService.show();
        return next.handle(req).pipe(map(event => {
            if (event instanceof HttpResponse) {
                this.loaderService.hide();
            }
            return event;
        }));
    }

}

According to Allow passing misc data to http client options #18155 which still an opened issue.

You can see some of workaround.

  • Using HttpClient and adding metadata by abusing HTTP Headers.

Myuploadservice.ts

return this.http.post(`${this.baseURL}/fileupload/${id}`, formdata,{
  reportProgress: true,
  observe: 'events',
  headers: { hideLoader: 'true' } // add header param
});

loader-interceptor.ts

intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    
   if (req.headers.has('hideLoader')) {
    const headers = req.headers.delete('hideLoader');
    req = req.clone({ headers });
   } else{
    this.loaderService.show();
   }
    return next.handle(req).pipe(map(event => {
        if (event instanceof HttpResponse) {
           this.loaderService.hide();
        }         
        return event;
    }));

Passing metadata for interceptors to Angular HttpClient

// MyRequestOptions is a remnant from a preivous implementation that redeclared HttpRequestOptonArgs with more props

export interface MyRequestOptions {
  skipErrorHandler?: boolean;
  hideLoader?: boolean;
  external?: boolean;
  suppressError?: boolean;
  ignoreSomething?: boolean;
}

const LoadInterceptorMeta = (options: MyRequestOptions): {params: HttpParamsWithMeta} => {
  const params: HttpParamsWithMeta = withMeta();
  const {skipErrorHandler, suppressError, external, hideLoader, ignoreCrId} = options;

  [
    new LoaderInterceptorConfig(hideLoader),
    new ExernalInterceptorConfig(external),
    new ErrorInterceptorConfig(skipErrorHandler, suppressError),
    new SomethingInterceptorConfig(ignoreSomething)
  ].forEach(interceptor => params.meta.add(interceptor));

  return {params};
};

@Injectable({
  providedIn: 'root'
})
export class HttpFacetService {

  constructor(private http: HttpClient) { }

  get(url: string, options: MyRequestOptions) {
    return this.http.get(url, LoadInterceptorMeta(options));
  }

Try to add an additional param to your request:

    const params = new HttpParams().set('Hide-Loader', 'true');
    
    return this.httpClient.get(path, { params });

after that you can read this param in your interceptor:

    const hideLoader = req.params.get('Hide-Loader');
    
    if (hideLoader) {
        this.isLoading.next(false);
        // and don't forget to remove this param:
        req = req.clone({ params: req.params.delete('Hide-Loader','true') });
    }
Related