I have implemented a splash screen in my app, as this way:
index.html:
<app-root></app-root>
<div class="splash spinner"></div>
css:
// ... Styles about spinner
app-root:empty + .splash {
opacity: 1;
}
Ok, in this case, the app-root when it's empty, I have a spinner animation and there is no problem, it works fine.
But, my problem comes now, I have lazy loading in routing:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AuthGuard } from './core';
import {
...
} from './auth';
export const routes: Routes = [
{
..
},
{
path: 'api',
loadChildren: 'app/api/myapi.module#MyApiModule',
canActivate: [ AuthGuard ],
},
},
];
@NgModule({
imports: [
RouterModule.forRoot(routes, {
enableTracing: true
}),
],
exports: [ RouterModule ]
})
export class AppRoutingModule { }
In /apis path I'm lazy loading MyApiModule, and inside MyApiModule, I have another routing:
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { MyComponent } from './mycomponent.component';
import { OtherComponent } from './othercomponent.component';
const routes: Routes = [
{
path: '',
component: MyComponent,
children: [
{
path: '',
component: OtherComponent,
},
{
path: ':id/api',
loadChildren: 'app/api/api2/api.module#ApiModule',
},
],
},
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class OtherRoutingModule { }
I want to show the same splash screen as I set in 'app-root' when my app is loading a 'lazy-loaded' module (the ApiModule module).
The goal is to show splash screen when a lazy module is loading so, my question is, is there any 'easy' way to catch when a load-children module is loaded (by events or something)? Or I need to accomplish the same way as I did (check in css the router-outlet... etc etc).
app-root:empty selector is more of a hack rather than universal solution for loading indicator. This or similar selector can still be additionally used for initially rendered page when scripts aren't loaded yet.
Loading indicator may be shown in some common scenarios:
Http, HttpClient, native XHR, ...)All of these scenarios can occur independently (e.g. triggered by components) or be applicable to Angular application phases that may cause visible delays:
It always depends on the case whether a spinner should be triggered at lower (scenarios) or higher (phases) level.
Some scenarios can be conventionally handled (HttpClient requests can be tracked with interceptors).
Some scenarios cannot be efficiently handled. This includes ES and Angular lazy-loaded modules, since they are handled at low level and usually don't expose a promise to chain.
So lazy-loaded Angular modules leave the only option to trigger a spinner, i.e. on route change:
router.events.subscribe(e => {
if (e instanceof NavigationStart) {
// show spinner
} elseif (e instanceof NavigationEnd {
|| e instanceof NavigationError
|| e instanceof NavigationCancel) {
// hide spinner
}
});
If some of asynchronous scenarios occur outside of route resolvers, HttpClient interceptors can be additionally involved.
Since several processes that trigger a spinner may occur simultaneously, a spinner should be implemented with a counter and not boolean flag, like is shown here.
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