Mellville
Mellville

Reputation: 1097

Global spinner not displaying with routing events

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

Answers (1)

Poul Kruijt
Poul Kruijt

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:

  1. 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

  2. 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

  3. 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

Related Questions