Angular5 - Récupérer tous les paramètres d'une route

Sur l'application qu'on m'a demandé de réaliser pendant mon stage, j'ai très souvent besoin de récupérer les paramètres de la route courante pour faire des appels sur l'API.
Par exemple, pour la route fictive :

http://stouder.dev/category/:categoryId/posts/:postId/comments/:commentId

La subtilité réside dans le fait qu'une instance de ActivatedRoute ne contient, entre autres choses, que ses propres paramètres ainsi qu'une référence à la route parente. Je me retrouvais donc régulièrement avec quelque chose comme

this.route.parent.parent.parent.featureId

La solution que j'ai trouvé à cela, c'est de créer un service qui loop sur tous les parents d'une route pour merger tous les paramètres en un seul objet.

Voici donc le code du service :

import { Injectable } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import 'rxjs/add/operator/first';
import 'rxjs/add/operator/toPromise';

@Injectable()
export class RouteParams {
  constructor(private route: ActivatedRoute) { }

  get params(): Promise<any> {
    return new Promise(async resolve => {
      const params: any = {}
      for (let i = 0; i < this.route.pathFromRoot.length; i++) {
        const paramMap = await this.route.pathFromRoot[i].paramMap.first().toPromise()
        for (const key of paramMap.keys)
          params[key] = paramMap.get(key);
      }
      resolve(params);
    })
  }
}

Petite subtilité néanmoins : le service doit absolument être fourni au niveau du composant pour que l'instance d'ActivatedRoute lui soit relative. Il est donc nécessaire de l'ajouter à la liste des providers du composant.

@Component({
  [...]
  providers: [RouteParams]
})
[...]

C'en est terminé pour ce petit tip. N'hésitez pas à partager l'article (à des dévs, pas à votre grand-mère) si vous l'avez apprécié et à le commenter en cas de questions ou de remarques !

Xavier Stouder

Read more posts by this author.