Kumar Sambhav
Kumar Sambhav

Reputation: 7765

Angular 5 | Rendering progress bar using HttpInterceptor

I am trying to add a material progress-bar in my Angular 5 application using a HttpInterceptor.

Whenever there are any outstanding XHR requests, the progress bar should be visible and should be hidden/removed when there are no pending XHR requests.

Here is my HttpInterceptor implementation that keeps track of pending request count :-

import {HttpEvent, HttpHandler, HttpInterceptor, HttpRequest} from '@angular/common/http';
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/observable/interval';
import 'rxjs/add/operator/publish';

@Injectable()
export class ProgressBatHttpInterceptorService implements HttpInterceptor {
  obs: Observable<number>; // PROBLEM: How to expose this as hot Obeservable ?
  private count = 0;

  constructor() {
    this.obs = Observable
      .create(observer => observer.next(this.count))
      .publish();
  }

  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    this.count++;   // increment the count here
    const observable = next.handle(req);
    observable.subscribe(() => {
    }, () => {
    }, () => {
      --this.count; // decrements the count.
    });
    return observable;
  }
}

AppComponent :-

import {Component} from '@angular/core';
import {ProgressBatHttpInterceptorService} from './progress-bat-http-interceptor.service';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  constructor(progress: ProgressBatHttpInterceptorService) {
    const obs = progress.obs;
    obs.subscribe(function (n) { // This never gets invoked.
      console.log(n);
    });
  }
}

The ProgressBatHttpInterceptorService is injected into AppComponent. In AppComponent constructor I am trying to subscribe to the count observable created in ProgressBatHttpInterceptorService.

I am planning to use the count Observable to conditionally show hide the progress bar.

PROBLEM

The .subscribe doesn't prints anything to console.

What's the correct way to create a hot observable for keeping track of outstanding request count ?

Upvotes: 0

Views: 1961

Answers (1)

Fan Cheung
Fan Cheung

Reputation: 11360

You can use a subject

obs: Subject<number>=new Subject();
 intercept(req: HttpRequest<any>, next: HttpHandler): 
 Observable<HttpEvent<any>> {
this.count++;   // increment the count here
const observable = next.handle(req).share(); // without share() , every call will be triggered twice
obs.next(this.count)
observable.subscribe(() => {
}, () => {
}, () => {
  --this.count; 
  obs.next(this.count)// decrements the count.
});
return observable;
}

Upvotes: 2

Related Questions