
Imaginez la situation : vous voulez lister la liste des ingrĂ©dients de votre recette favoris … et … il est affichĂ© : « aucun ingrĂ©dient n’est prĂ©sent ». Puis quelques secondes plus tard : ça y est vos ingrĂ©dients sont lĂ . Frustrant, non ? En tout cas peu ergonomique.
La faute au temps de chargement
Tout est bien fait : vous avez bindé votre template html à votre component. Vous avez bien utilisé RxJs et les Observables.
Oui, mais .. c’est asynchrone. Et le serveur met du temps Ă charger.
Vive la barre de chargement
Le rĂ©flexe ici, qu’on ne voit hĂ©las pas tout le temps sur les applications SPA : ajouter une image de chargement tant que notre liste n’est pas renseignĂ©e.
Optimier avec le Resolver
Le resolver est une classe injectable qui va se présenter pour une route. Elle va permettre de précharger les données avant affichage / génération du composant.
CrĂ©ation dâune classe Resolver
(ici nous utilisons ngRx pour le chargement des wookies)
@Injectable()
export class WookieResolver implements Resolve<any> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<any> {
return this.store.pipe(
tap(() => {
this.store.dispatch(loadAllWookies());
}),
first()
);
}
}
Référencement dans la partie routing liée
const routes: Routes = [
{
path: '',
component: WookieListComponent,
resolve: {
wookies: WookieResolver
}
},
];
Ajout dans les providers
@NgModule({
declarations: [WookieListComponent],
imports: [
CommonModule,
WookieRoutingModule
],
providers: [
WookieResolver
]
})
export class WookieModule { }
Récupération des éléments dans notre composant
@Component([...])
class WookieComponent implements ngOnInit {
constructor(private route: ActivatedRoute) {}
ngOnInit() {
this.route.data.subscribe((data: { wookies: Wookie[] }) => this.wookies = data.wookies);
}
}
On note ici que l’on rĂ©cupĂšre les wookies qui ont Ă©tĂ© passĂ©s par le Resolver depuis la route.
De plus, le route.data.subscribe nous permet de s’inscrire au changement : donc c’est un comportement rĂ©actif !
Faire patienter l’internaute avec un Spinner et le router navigation
Ajout sur le composant parent du spinner
<div *ngIf="pageLoading">
<img src="https://i.pinimg.com/originals/90/80/60/9080607321ab98fa3e70dd24b2513a20.gif">
</div>
Et détection de la navigation
this.router.events.subscribe(event => {
switch(true) {
case event instanceof NavigationStart: {
this.pageLoading = true;
console.info('loading', this.pageLoading);
break;
}
case event instanceof NavigationEnd:
case event instanceof NavigationCancel:
case event instanceof NavigationError: {
console.info('loading', this.pageLoading);
this.pageLoading = false;
break;
}
}
})
Et voilĂ , nous avons des routes et des composants plus optimisĂ©s, qui ne se chargent que lorsque les donnĂ©es sont valides ! đ
Happy coding ! đ