Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

display a pre-loader in Angular before it load first component

I'm using Angular 6.

My application takes a few seconds before it loads the component and that time is spent in loading resources and validating the user.

While all this happens, my application displays a blank white page.

I want to replace that ugly white page with a preloader that will be displayed until all background process is complete.

For that I have added a CSS loading spinner inside the index.html like

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>My App</title>
  <base href="/">

  <!-- Fonts and icons -->

</head>
<body>
  <app-root>
    <!-- Pre-loading spinner -->
    <!-- This code within the app-root will be wiped of once the child component is loaded -->
    <!-- This code will not even be shown in the source code once the child component is loaded -->
    <!-- We can put any code css/html/image/etc here -->

    <style>
      /** CSS here. Since it will be wiped totally, 'll not cause any impact to the core stylesheet.
    </style>

    Loading<span class="d">.</span><span class="d d-2">.</span><span class="d d-3">.</span>
  </app-root>
</body>
</html>

And this displays a page like

enter image description here

But the issue is that. The first loaded component is app.component.html which has following content

<router-outlet></router-outlet>

Which further loads another component admin-layout-component.html with contents

<div class="wrapper">
  <div class="sidebar" data-color="red">
    <app-sidebar></app-sidebar>
  </div>
  <div class="main-panel">
    <app-navbar></app-navbar>
    <router-outlet></router-outlet>
    <app-footer></app-footer>
  </div>
</div>

As soon as app.component is loaded, the spinner content from index.html is removed and start displaying the blank page until admin-layout is loaded.

I tried adding same styling code inside the router-outlet of app.component.html but then when the component is loaded, the contents are added along with the spinner and spinner is not removed from other pages.

How can I display the spinner on app.component.html as well until dashboard page is loaded.

Here is a video how it is working: https://youtu.be/RSlTi0EQHm4

like image 718
Anuj TBE Avatar asked Oct 14 '18 18:10

Anuj TBE


2 Answers

Component

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

export class AppComponent{/* Not need remove element or change style*/}

index.html

<body osk-root><!--YOUR LOADER--></body>

after appcomponent succefully loaded , angular clears innerHtml of body[osk-root] element

(Note I use like as this in Angular 9)

like image 176
OMANSAK Avatar answered Sep 18 '22 13:09

OMANSAK


I got this working in Angular 8, based on Sunil's answer. I'm hiding the loader element from the App Component, which is initialized before any other component. So no need to add this everywhere.

Manipulating the DOM using ElementRef is not recommended so I'm using Renderer2 instead.

index.html:

<body class="theme-primary">
  <div id="loader">
    <style>
      .application-loading-container {
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        height: 100vh;
      }

      .application-loading-box {
        width: 300px;
        margin: 5px;
        text-align: center;
      }
    </style>
    <div class="application-loading-container">
      <div class="application-loading-box"><h2>Loading...</h2></div>
    </div>
  </div>
  <app-root></app-root>
</body>

app.component.ts:

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

export class AppComponent implements AfterViewInit {
  constructor(private renderer: Renderer2) {}

  ngAfterViewInit() {
    let loader = this.renderer.selectRootElement('#loader');
    this.renderer.setStyle(loader, 'display', 'none');
  }
}
like image 33
Jimmy Garpehäll Avatar answered Sep 18 '22 13:09

Jimmy Garpehäll