Show navigation loader spinner with delay in angular 2+

Viewed 4447

I'm new to angular 2+ and RxJS, trying to get used to RxJS.

I show load spinner on route transitions, but only if it takes more then certain amount time, lats say 160ms
I have a load spinner as a separate component, with subscription to ngrx store, so I show/hide load spinner based on value in the sore (showSpinner)

In my app root component, I subscribe to router change events, and dispatch actions (SHOW_SPINNER/HIDE_SPINNER)
So the question is, Is there a simpler way to achieve it?

Here are parts of my code

....

export const navigationStreamForSpinnerStatuses = {
  NAVIGATION_STARTED: 'NAVIGATION_STARTED',
  NAVIGATION_IN_PROGRESS: 'NAVIGATION_IN_PROGRESS',
  NAVIGATION_ENDED: 'NAVIGATION_ENDED'
};

....

private navigationStartStream;
private navigationStartStreamWithDelay;
private navigationFinishStream;

constructor(private store: Store<IAppState>, private router: Router) {
  this.navigationStartStream = router.events
    .filter(event => {
      return event instanceof NavigationStart;
    })
    .map(() => navigationStreamForSpinnerStatuses.NAVIGATION_STARTED);

  this.navigationStartStreamWithDelay = this.navigationStartStream
    .delay(160)
    .map(() => navigationStreamForSpinnerStatuses.NAVIGATION_IN_PROGRESS);

  this.navigationFinishStream = router.events
    .filter(event => {
      return event instanceof NavigationEnd || event instanceof NavigationCancel || event instanceof NavigationError;
    })
    .map(() => navigationStreamForSpinnerStatuses.NAVIGATION_ENDED);

  this.navigationStartStream
    .merge(this.navigationFinishStream)
    .merge(this.navigationStartStreamWithDelay)
    .pairwise()
    .subscribe([previousStatus, currentStatus] => {
      if (previousStatus !== navigationStreamForSpinnerStatuses.NAVIGATION_ENDED && currentStatus === navigationStreamForSpinnerStatuses.NAVIGATION_IN_PROGRESS) {
        this.store.dispatch({ type: StateLoaderSpinnerActionsTypes.SHOW_SPINNER });
      } else if (previousStatus === navigationStreamForSpinnerStatuses.NAVIGATION_IN_PROGRESS && currentStatus === navigationStreamForSpinnerStatuses.NAVIGATION_ENDED) {
        this.store.dispatch({ type: StateLoaderSpinnerActionsTypes.HIDE_SPINNER });
      }
    });
}
2 Answers
Related