Comment exploiter le Router State d'Angular pour transporter des données ?

Comment exploiter le Router State d'Angular pour transporter des données ?

Le Routeur d'Angular nous permet de transmettre des informations lors de la navigation entre nos différents composants. Dans cet exemple spécifique, nous utilisons routerLink en associant l'attribut state pour transférer au composant routé le post sélectionné parmi une liste de posts affichés :

<li [routerLink]="['/post']" [state]="{selectedPost: post}>

Nous observons que l'attribut state est une entrée @Input de la directive routerLink. Nous pouvons y assigner n'importe quel type d'objet. Les données transmises sont ajoutées à l'objet history.state du navigateur web, offrant ainsi une méthode pratique pour transférer des données à une bibliothèque non-angular, par exemple.

Le composant routé peut accéder aux données envoyées via router.getCurrentNavigation(). Ces données sont stockées sous extras.state comme illustré ci-dessous :

router = inject(Router)
selectedPost = 
    this.router.getCurrentNavigation()?.extras?.state?.['selectedPost']

Le code complet est disponible ici sur Stackblitz. Dans cet exemple, nous avons une application avec une liste de posts publiés. Lorsqu'on clique sur le titre d'un post, les détails de ce post s'ouvrent dans un nouveau composant. Le post sélectionné est transmis au composant via le mécanisme du Router State.

Cette approche nous permet de transmettre des données à un composant sans recourir aux paramètres d'URL, ce qui simplifie la configuration des routes, comme illustré ci-dessous :

...

provideRouter(
    [
        { path: '', component: PostsComponent },
        { path: 'post', component: PostComponent },
    ],
)

Voici le résultat final :

Pour rappel, voici comment serait la configuration avec les paramètres d'URL :

...

provideRouter(
    [
        { path: '', component: PostsComponent },
        { path: 'post/:id', PostComponent }
    ]
)

Voici le lien de navigation :

<li [routerLink]="['/post', post.id]">

Il est important de noter que seul l'ID du post a été transmis avec cette approche; il sera nécessaire de récupérer l'objet complet en effectuant une requête vers le service backend, par exemple. La récupération de l'ID côté composant routé peut être réalisée comme suit :

....

subscription: Subscription;
id: String;

constructor(private route: ActivatedRoute){}
ngOnInit(): void {
    this.subscription.add(
        this.route.params.subscribe(params => {
            this.id : params['id'];
        })
    );
}

ngOnDestroy(): void {
    this.subscription.unsubscribe();
}