Améliorer vos routes avec le Resolver dans Angular pour un meilleur chargement !

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 ! 🙂

Notre adresse

1 rue du guesclin
44000 Nantes

Notre téléphone

+33 2 79 65 52 87

Société

DevToBeCurious SARL
84860163900018 - Nantes B 848 601 639