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
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
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)
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');
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With