Creating the loading in Angular

1. Introduction

Loading is essential in a website, it can let the user know the flow is processing, otherwise user will not know what’s happening. So, I will introduce an excellent loading package to help you solve the loading issue!

2. ngx-loading

ngx-loading is a very nice and customizable loading spinner for Angular, there are flexible config options that let you setup different loading styles. You can install ngx-loading with the below command

Do you want to be a good trading in cTrader?   >> TRY IT! <<
npm install --save ngx-loading

And you can find the base usage in github

3. Use in the common layout

With normal usage, you need to add the below code in each html page, so in this article, I will show you how to use the ngx-loading in a common layout.

<ngx-loading
    [show]="loading"
    [config]="{ backdropBorderRadius: '3px' }"
    [template]="customLoadingTemplate"
></ngx-loading>

3.1. Create the service

The concept is we will put the ngx-loading in the common (or parent) page’s HTML layout, so we can’t control it in the child page directly, the solution is we can use a Subject.

The Subject is a special type of Observable that allows values to be multicasted to many Observers. Subjects are like EventEmitters.

So we can create a service to handle the Subject. Suppose we just need to control start and stop to show the loading in needs, so create these two methods in the service, and don’t forget to release the object, the complete code as below:

import { Injectable, OnDestroy } from "@angular/core";
import { Subject } from "rxjs";


@Injectable({
  providedIn: 'root',
})
export class LoadingService implements  OnDestroy {
  // Observable string sources
  private emitChangeSource = new Subject<boolean>();
  // Observable string streams
  changeEmitted$ = this.emitChangeSource.asObservable();

  // Start loading
  start() {
    this.emitChangeSource.next(true);
  }

  // Stop loading
  stop() {
    this.emitChangeSource.next(false);
  }

  ngOnDestroy() {
    // complete and release the subject
    this.emitChangeSource.complete();
  }
}

3.2. Add the ngx-loading to the layout

1) Import the NgxLoadingModule in your root app module

import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";
import { CoreModule } from "./core/core.module";
import { NgxLoadingModule } from "ngx-loading";

@NgModule({
  //...
  imports: [
    //...
    NgxLoadingModule.forRoot({}),
  ],
  //...
})
export class AppModule {}

2) Create a loading flag and config in the main layout backend(.ts) file

const PrimaryRed = '#dd0031';
const SecondaryBlue = '#1976d2';

//...

//set the loading flag
loading = false;
//set the loading config
//reference:  https://github.com/Zak-C/ngx-loading#config-options
config = {
  animationType: ngxLoadingAnimationTypes.threeBounce,
  primaryColour: PrimaryRed,
  secondaryColour: SecondaryBlue,
  tertiaryColour: PrimaryRed,
  backdropBorderRadius: '3px',
};

3) Subscribe and update the loading status in the main layout

// Update loading status
this.loadingService.changeEmitted$.subscribe(isLoading => {
  //console.log(isLoading);
  this.loading = isLoading;
});

4) Add the loading HTML code in the main layout frontend(.html) file

<ngx-loading #ngxLoading [show]="loading" [config]="config" [template]="loadingTemplate"></ngx-loading>
  <ng-template #loadingTemplate>
    <div class="loading-class">
      <h4>Please wait ...</h4>
    </div>
</ng-template>

Ok, now, we just need to control the loading flag in other child pages with LoadingService

4. Usage in child pages

We still using this code for the demo. Apply the loading when doing login, so we set the private loadingService: LoadingService in the login component’s constructor, and call this.loadingService.start(); after submitting the login form, and then call this.loadingService.stop(); when success or failed login:

  constructor(//...
    private loadingService: LoadingService) {
  }

  //login
login() {

 //start the loading
 this.loadingService.start();

 this.auth
   .login(this.username.value, this.password.value)
   .pipe(filter(authenticated => authenticated))
   .subscribe(
     () => {
       console.log('after logined and redirect');

       //stop the loading
       this.loadingService.stop();

       this.router.navigateByUrl('/user-management');
     },
     (errorRes: HttpErrorResponse) => {

       //stop the loading
       this.loadingService.stop();

       if(errorRes.status == 401){
        //...
       }
       console.log('Error', errorRes);
     }
   );
}

After clicking the login button, it will show the loading as below

5. Conclusion

If we want to control the parent component in the child, we need to subscribe to the change status and update it in the child, so we can use the Subject and create a service for that! This is the same concept as this article to use the SweetAlert2 in angular.

Loading

Views: 18
Total Views: 315 ,

One thought on “Creating the loading in Angular

Leave a Reply

Your email address will not be published. Required fields are marked *