How to add a spinner before loading a new page in angular?

Viewed 3989

So I want to add a spinner like in the ngx-admin project http://akveo.com/ngx-admin/

I have added the spinner to my index.html, the spinner appears, but then just my navbar is getting rendered and the spinner continues to spin where the module should be displayed. The navbar is only called in the module it self and not in the routing module, that's why I am so confused that it doesn't work.

<body>
<app-root>Loading...</app-root>

  <style>
      @-webkit-keyframes spin {
        0% {
          transform: rotate(0)
        }

        100% {
          transform: rotate(360deg)
        }
      }

      @-moz-keyframes spin {
        0% {
          -moz-transform: rotate(0)
        }

        100% {
          -moz-transform: rotate(360deg)
        }
      }

      @keyframes spin {
        0% {
          transform: rotate(0)
        }

        100% {
          transform: rotate(360deg)
        }
      }

      .spinner {
        position: fixed;
        top: 0;
        left: 0;
        width: 100%;
        height: 100%;
        z-index: 1003;
        background: #000000;
        overflow: hidden
      }

      .spinner div:first-child {
        display: block;
        position: relative;
        left: 50%;
        top: 50%;
        width: 150px;
        height: 150px;
        margin: -75px 0 0 -75px;
        border-radius: 50%;
        box-shadow: 0 3px 3px 0 rgb(25, 136, 2);
        transform: translate3d(0, 0, 0);
        animation: spin 2s linear infinite
      }

      .spinner div:first-child:after,
      .spinner div:first-child:before {
        content: '';
        position: absolute;
        border-radius: 50%
      }

      .spinner div:first-child:before {
        top: 5px;
        left: 5px;
        right: 5px;
        bottom: 5px;
        box-shadow: 0 3px 3px 0 rgb(85, 255, 6);
        -webkit-animation: spin 3s linear infinite;
        animation: spin 3s linear infinite
      }

      .spinner div:first-child:after {
        top: 15px;
        left: 15px;
        right: 15px;
        bottom: 15px;
        box-shadow: 0 3px 3px 0 rgb(15, 109, 2);
        animation: spin 1.5s linear infinite
      }

    </style>
    <div id="nb-global-spinner" class="spinner">
      <div class="blob blob-0"></div>
      <div class="blob blob-1"></div>
      <div class="blob blob-2"></div>
      <div class="blob blob-3"></div>
      <div class="blob blob-4"></div>
      <div class="blob blob-5"></div>
    </div>
</body>

</html>
2 Answers

You should put the spinner inside of the app-root element. It will be replaced by the Angular application once the application has finished loading:

<body>
  <app-root>
    <!-- The spinner content goes here -->
  </app-root>
</body>

To display the spinner while a specific view is loading, you can wrap it in a spinner component:

import { Component } from '@angular/core';

@Component({
  selector: 'spinner',
  template: `
    <style>
      ...
    </style>
    <div id="nb-global-spinner" class="spinner">
      ...
    </div>  
  `,
})
export class SpinnerComponent { }

and add it to the appropriate module:

...
import { HomeComponent } from './home.component';
import { SpinnerComponent } from './spinner.component';

@NgModule({
  declarations: [ 
    ...
    HomeComponent,
    SpinnerComponent
  ],
  ...
})
export class MyModule { }

In the destination page template (e.g. home.component.html), you can use an ngIf ... else directive to display the spinner component while the page is still loading:

<div *ngIf="isDataReady; else spinner">
  <!-- Normal page template here -->
</div>
<ng-template #spinner>
  <spinner></spinner>
</ng-template>

See this stackblitz for a demo. The spinner is diplayed while the Home page data is loading.

Best way is to subscribe to the Router events and set the spinner accordingly.

Please see the picture for more info.

enter image description here

enter image description here

You can show the spinner when this.loading = true, simply using a *ngIf in the app.component.html file.

Related