Search code examples
angularngx-bootstrap

Loading component in Angular2/4


I'm creating an app in angular 4 and I want to have a loading component so the user can realize that he submit a form and the app is doing something, and that the app is waiting for information from the backend.

I did it in angularjs through having a loader component and sharing the action to hide or show using the $rootScope... But in angular2/4 I don't see how I can do this.

Ideally I need to have a loading component that will be over a form or some section of the page (when the information that belongs to that section is being retrieve) or maybe over the full screen.

Could you please give a clue about how to do this?

Thanks!


Solution

  • You will want to create a loading service that can store a reference to your loading component. Then inject that loading service in the constructor of other components that need to be able to toggle that loading component.

    import { Injectable } from '@angular/core';
    import { LoadingComponent } from './loading.component';
    
    @Injectable()
    export class LoadingService {
      private instances: {[key: string]: LoadingComponent} = {};
    
      public registerInstance(name: string, instance: LoadingComponent) {  
        this.instances[name] = instance;
      }
    
      public removeInstance(name: string, instance: LoadingComponent) {
        if (this.instances[name] === instance) {
          delete this.instances[name];
        }
      }
    
      public hide(name: string) {
        this.instances[name].hide();
      }
    
      public show(name: string) {
        this.instances[name].show();
      }
    }
    

    Be sure to register your LoadingService in your Module's providers array!

    Then in the LoadingComponent you can inject the LoadingService, so that the LoadingComponent can register itself with the LoadingService it should register itself with that service:

    import { Component, OnInit, Input, OnDestroy } from '@angular/core';
    import { LoadingService } from './loading.service';
    
    @Component({
      selector: 'yourapp-loading',
      templateUrl: './loading.component.html',
      styleUrls: ['./loading.component.scss']
    })
    export class LoadingComponent implements OnInit, OnDestroy {
      @Input() name: string;
      private isVisible = false;
    
      constructor(private service: LoadingService) {}
    
      ngOnInit() {
        if (this.name) {
          this.service.registerInstance(this.name, this);
        }
      }
    
      ngOnDestroy() {
        if (this.name) {
          this.service.removeInstance(this.name, this);
        }
      }
    
      /* ... code to show/hide this component */
    }