How to implement a global loader in Angular

Here is what I ended up with, after realizing that a delay was a good solution in terms of UX because it allowed the loader to show only when the loading time is worth displaying a loader.

I don’t like this solution because I prefer when the state is being encapsulated into Observable operators rather than in a shared variable but I couldn’t achieve it.

counter = 0;

router.events.pipe(
  filter(x => x instanceof NavigationStart),
  delay(200),
).subscribe(() => {
  /*
  If this condition is true, then the event corresponding to the end of this NavigationStart
  has not passed yet so we show the loader
  */
  if (this.counter === 0) {
    loaderService.show();
  }
  this.counter++;
});

router.events.pipe(
  filter(x => x instanceof NavigationEnd || x instanceof NavigationCancel || x instanceof NavigationError)
).subscribe(() => {
  this.counter--;
  loaderService.hide();
});

Leave a Comment