Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Display Loading Icon on Route Resolver / Route Change

Im trying to show a loading icon while I the route resolver gets the data from the DB.

I've tried the below option:

Root Component:

_router.events.subscribe((routerEvent: RouterEvent) => {

   if (routerEvent instanceof NavigationStart) {
      console.log("start");
      this.loading = true;

   } else if (routerEvent instanceof NavigationError || NavigationCancel || NavigationEnd) {
    console.log("end");
    this.loading = false;
  }

});

Root Component HTML:

<h1 *ngIf="loading">Loading</h1>

The loading icon does not show at all.

The following is displayed on console log on every route change:

enter image description here

Update:

Below is the output after applying the following changes:

 public loading: boolean = true;

 console.log(routerEvent);

 console.log("Loading is " + this.loading);

enter image description here

Update 2:

app.component.html:

<div class="uk-offcanvas-content">
  <h1>{{loading}}</h1>
  <h1 *ngIf="loading">Loading</h1>

  <app-root-nav></app-root-nav>

  <app-notifications></app-notifications>

  <router-outlet></router-outlet> 
</div>

app.component.ts:

import {Component, OnInit, AfterViewInit} from '@angular/core';
import {AuthenticationService} from "../../authentication/services/authentication.service";
import {Router, Event, NavigationStart, NavigationEnd, NavigationCancel, NavigationError} from "@angular/router";

import {RouterEvent} from "@angular/router";
import UIkit from 'uikit'

@Component({
   selector: 'app-root',
   templateUrl: './app.component.html',
   styleUrls: ['./app.component.css']
 })

 export class AppComponent implements OnInit, AfterViewInit {

  isLoggedIn: boolean;
  public loading: boolean = true;
  UIkit: any;

  constructor(private _router: Router, private _authService: AuthenticationService) {

  _router.events.subscribe((routerEvent: RouterEvent) => {
    if (routerEvent instanceof NavigationStart) {

      this.loading = true;
      console.log(routerEvent);
      console.log("Loading is " + this.loading);

  } else if (routerEvent instanceof NavigationError || NavigationCancel || NavigationEnd) {

    this.loading = false;
  }
});
}

ngAfterViewInit() {
}

ngOnInit() {

  UIkit.notification({
    message: 'my-message!',
    status: 'primary',
    pos: 'top-right',
    timeout: 5000
  });

 }

}
like image 839
Skywalker Avatar asked Oct 18 '22 00:10

Skywalker


1 Answers

The problem here is pretty simple but easy to miss. you're improperly checking for the router event type, it should be like :

else if (routerEvent instanceof NavigationError || routerEvent instanceof NavigationCancel || routerEvent instanceof NavigationEnd)

the way you have it is just returning true always because your second clause is basically "or if NavigationCancel is truthy", which it is by definition since it's an existing type. so loading sets to false immediately when the route resolve starts since there are a lot of intermediate router events before NavigationEnd event and it sets to false on all of them due to the way you're checking.

plunk: https://plnkr.co/edit/7UKVqKlRY0EPXNkx0qxH?p=preview

like image 109
bryan60 Avatar answered Oct 30 '22 18:10

bryan60