Search code examples
angularangular2-routingloading-image

How to display loading screen while routing using navigation in Angular2?


I've tried this solution but could'nt get it working. I'm completely new to Angular2 (with no knowledge of AngularJS). Well the loading screen does'nt show up, I guess I need to add some time out so that it gets some time to be displayed but where and how I don't know.

app.component.ts

import {Component} from '@angular/core';
    import {
      Router,
      // import as RouterEvent to avoid confusion with the DOM Event
      Event as RouterEvent,
      NavigationStart,
      NavigationEnd,
      NavigationCancel,
      NavigationError
    } from '@angular/router';

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

    export class AppComponent {
    // Sets initial value to true to show loading spinner on first load
      loading = true;

      constructor(private router: Router) {
        router.events.subscribe((event: RouterEvent) => {
         this.navigationInterceptor(event);
      });
    }

      // Shows and hides the loading spinner during RouterEvent changes
      navigationInterceptor(event: RouterEvent): void {
        if (event instanceof NavigationStart) {
          this.loading = true;
        }
        if (event instanceof NavigationEnd) {
          this.loading = false;
        }

        // Set loading state to false in both of the below events to hide the spinner in case a request fails
        if (event instanceof NavigationCancel) {
          this.loading = false;
        }
        if (event instanceof NavigationError) {
          this.loading = false;
        }
      }


app.component.html

<a [routerLink]="['/ArrayOP']"><button>Array operation</button></a>
<a [routerLink]="['/Calci']"><button>Calculator</button></a>
<div class="loading-overlay" *ngIf="loading">
  Loading<span class="d">.</span><span class="d d-2">.</span><span class="d d-3">.</span>
</div>
<router-outlet></router-outlet>

I want to achieve that the loading screen shows up in every routing in whole application and the loading screen that I'm trying to show up is this (code reference). Any suggestion would be of great help.


Solution

  • I found the solution. Posting it if anyone needs it in future.
    This is what I did... I added setTimeout functionality to the app.component.ts as

    import {
      Component
    } from '@angular/core';
    import {
      Router,
      // import as RouterEvent to avoid confusion with the DOM Event
      Event as RouterEvent,
      NavigationStart,
      NavigationEnd,
      NavigationCancel,
      NavigationError
    } from '@angular/router';
    
    @Component({
      selector: 'app-root',
      templateUrl: './app.component.html',
      styleUrls: ['./loadingCSS.css']
    })
    
    export class AppComponent {
      // Sets initial value to true to show loading spinner on first load
      loading = true;
    
      constructor(private router: Router) {
        router.events.subscribe((event: RouterEvent) => {
          this.navigationInterceptor(event);
        });
      }
    
      // Shows and hides the loading spinner during RouterEvent changes
      navigationInterceptor(event: RouterEvent): void {
        if (event instanceof NavigationStart) {
          this.loading = true;
        }
        if (event instanceof NavigationEnd) {
          setTimeout(() => { // here
            this.loading = false;
          }, 2000);
        }
    
        // Set loading state to false in both of the below events to hide the spinner in case a request fails
        if (event instanceof NavigationCancel) {
          setTimeout(() => { // here
            this.loading = false;
          }, 2000);
        }
        if (event instanceof NavigationError) {
          setTimeout(() => { // here
            this.loading = false;
          }, 2000);
        }
      }
    


    And changed the HTML as

    <div class="loading-overlay" *ngIf="loading">
      Loading<span class="d">.</span><span class="d d-2">.</span><span class="d d-3">.</span>
    </div>
    <div *ngIf="!loading">
      <router-outlet></router-outlet>
    </div>