Reputation: 1097
I have this code on my app component HTML
<mat-progress-spinner *ngIf="loading"></mat-progress-spinner>
<router-outlet></router-outlet>
And the TS
export class AppComponent {
loading: boolean;
constructor(private router: Router) {
this.router.events.subscribe((routerEvent: Event) => {
this.checkRouterEvent(routerEvent)
})
}
checkRouterEvent(routerEvent: Event): void {
if (routerEvent instanceof NavigationStart) {
this.loading = true;
console.log(this.loading)
}
if (routerEvent instanceof NavigationCancel ||
routerEvent instanceof NavigationEnd ||
routerEvent instanceof NavigationError) {
this.loading = false
console.log(this.loading)
}
}
}
I learned this technique with video by Deborah Kurata. But I never see the spinner and I have lots of images in my app when loading the page. What am I doing wrong? Any ideas?
EDIT:
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush,
})
With the onPush changedetection, the images don't appear, so I'm kind of lost here...
EDIT:
App-routing:
//const adminModule = ()=> import('./admin/admin.module').then(m=>m.AdminModule);
const routes: Routes = [
{
path: '', component:ShellComponent,
children: [
{path: 'home', component: HomeComponent, canActivate:[AuthGuardService] },
//{path: 'admin', loadChildren: adminModule},
{path: 'detail/:id', component: DetailComponent, },
{path: '', redirectTo:'home', pathMatch:'full'},
{path: 'table', component:ListBooksComponent},
{path: 'selection', component: SelectionComponent, },
{path:'edit/:id', component:RegisterComponent, canDeactivate:[EditGuardService]},
]
},
{path: 'login', component: LoginComponent},
{path:'edit/:id', component:RegisterComponent},
{path:'register', component: RegisterComponent}
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
Upvotes: 1
Views: 354
Reputation: 71901
First of all the loading of images will not stop the navigation and is not part of the navigation life cycle.
Are you by any chance using ChangeDetectionStrategy.OnPush
in your app component? If so, one way to do it, is to make it an Observable
. Which is a cleaner solution anyways:
<mat-progress-spinner *ngIf="loading$ | async"></mat-progress-spinner>
<router-outlet></router-outlet>
export class AppComponent {
readonly loading$: Observable<boolean> = this.router.events.pipe(
map((event) => this.checkRouterEvent(event))
);
constructor(private router: Router) {}
checkRouterEvent(routerEvent: Event): boolean {
if (routerEvent instanceof NavigationStart) {
return true;
}
if (routerEvent instanceof NavigationCancel ||
routerEvent instanceof NavigationEnd ||
routerEvent instanceof NavigationError) {
return false;
}
}
}
However, keep in mind that the only way you will be able to actually see the spinner, if the router has some resolving/guarding/loading to do. Which basically means:
Resolving: These are resolvers declared on the path you are navigating to. If these are async, like http calls, your spinner will show for the duration of the resolving
Guarding: These are the CanActivate
, CanActivateChild
, CanLoad
and the lesser known CanDeactivate
guards on your route config. Same counts here, if these are async there will be a spinner
Loading: This is the lazy loading of your feature modules. This is a path defined with the loadChildren
config. While the application is requesting the module, it will delay the router for as long as it's loading
If your route config does not have any of these 3 things, or they are not async, you will not see a spinner
Upvotes: 1