• 10 heures
  • Moyenne

Ce cours est visible gratuitement en ligne.

course.header.alt.is_video

course.header.alt.is_certifying

J'ai tout compris !

Mis à jour le 01/07/2024

Activez les routes avec ActivatedRoute

Il est très souvent utile dans une application dynamique d'avoir accès à la route active. Ce que ça va vous permettre de faire dans ce chapitre, c'est de créer une route avec un paramètreid  pour visualiser un seul FaceSnap. Le component que vous allez associer à cette route pourra récupérer cet  id  afin de demander à FaceSnapsService de lui envoyer le FaceSnap correspondant.

Commençons par créer le component qui sera, pour simplifier, une copie de FaceSnapComponent, mais avec une nuance quant au FaceSnap affiché.

Visualisez un seul FaceSnap

Générez un nouveau component appelé SingleFaceSnapComponent, et transposez-y tout depuis FaceSnapComponent : template, TS et styles.

Vous pouvez dès maintenant créer la route qui appellera ce component. Il faut que l'on puisse y passer un paramètre dynamique, c'est-à-dire le segment de la route qui contiendra l'id  du FaceSnap, et qui sera donc dynamique. Voilà comment faire :

const routes: Routes = [
  { path: 'facesnaps/:id', component: SingleFaceSnapComponent },
  { path: 'facesnaps', component: FaceSnapListComponent },
  { path: '', component: LandingPageComponent }
];

Les  :id  spécifient que ce qui se trouvera après  facesnaps/  correspondra à un paramètre qui s'appellera  id.

Problème ! On n'a aucun moyen de passer un FaceSnap au  @Input()  de ce component ! Comment fait-on pour récupérer l'id passé en paramètre de route ?

Heureusement, nous avons une solution !

Récupérez les paramètres de route

Afin de récupérer les informations de la route activée, vous allez injecterActivatedRoutedans SingleFaceSnapComponent, sans oublier d'enlever le décorateur  @Input()  de la propriété  faceSnap  :

export class SingleFaceSnapComponent implements OnInit {
  faceSnap!: FaceSnap;
  snapButtonText!: string;
  userHasSnapped!: boolean;

  constructor(private faceSnapsService: FaceSnapsService,
              private route: ActivatedRoute) {}

Ensuite, dans  ngOnInit(), vous allez pouvoir récupérer le paramètre  id  via le snapshot de la route (un snapshot est un aperçu instantané d'une valeur qui change au cours du temps) :

const faceSnapId = this.route.snapshot.params['id'];

Afin de pouvoir récupérer un FaceSnap par son id, je vous propose d'ajouter une méthode à FaceSnapsService, en refactorisant snapFaceSnapById par la même occasion :

// ...
@Injectable({
  providedIn: 'root'
})
export class FaceSnapsService {
  // ...
  
  getFaceSnapById(faceSnapId: string): FaceSnap {
    const foundFaceSnap = this.faceSnaps.find(faceSnap => faceSnap.id === faceSnapId);
    if (!foundFaceSnap) {
      throw new Error('FaceSnap not found!');
    }
    return foundFaceSnap;
  }

  snapFaceSnapById(faceSnapId: string, snapType: SnapType): void {
    const faceSnap = this.getFaceSnapById(faceSnapId);
    faceSnap.snap(snapType);
  }
}

Du coup, depuis SingleFaceSnapComponent, vous pouvez appeler la méthode  getFaceSnapById()  du service pour récupérer le FaceSnap correspondant à l'  id  récupéré :

const faceSnapId = this.route.snapshot.params['id'];
this.faceSnap = this.faceSnapsService.getFaceSnapById(faceSnapId);

La méthode  ngOnInit  commence à être un peu trop "busy", donc je vous propose d'en extraire deux méthodes privées :

// ...
export class SingleFaceSnapComponent implements OnInit {
  // ...
  ngOnInit(): void {
    this.prepareInterface();
    this.getFaceSnap();
  }
  
  // ...
  private prepareInterface() {
    this.snapButtonText = 'Oh Snap!';
    this.userHasSnapped = false;
  }

  private getFaceSnap() {
    const faceSnapId = this.route.snapshot.params['id'];
    this.faceSnap = this.faceSnapsService.getFaceSnapById(faceSnapId);
  }
}

Pour compléter l'application, et permettre à vos utilisateurs d'accéder à cette nouvelle route, je vous propose de modifier FaceSnapComponent pour n'afficher que le titre des FaceSnaps, et d'y ajouter un bouton qui permet d'ouvrir le FaceSnap dans la nouvelle route.

Du coup, le template donnera :

<div class="face-snap-card">
  <h2>{{ faceSnap.title | uppercase }}</h2>
  <button (click)="onViewFaceSnap()">VIEW</button>
</div>

Je vous laisse quelques instants pour tenter d'implémenter  onViewFaceSnap(), sans indice cette fois-ci.

Voilà ma solution. Il faut bien sûr injecter le Router, et utiliser sa méthode  navigateByUrl()  :

// ...
export class FaceSnapComponent {
  @Input() faceSnap!: FaceSnap;

  constructor(private router: Router) {}

  onViewFaceSnap() {
    this.router.navigateByUrl(`facesnaps/${this.faceSnap.id}`);
  }
}

Comme ça, votre page FaceSnaps ressemble à ça :

Les cards affichent seulement les titres et les descriptions, ainsi que les boutons VIEW
Les boutons VIEW

Et les boutons VIEW vous amènent vers les routes SingleFaceSnapComponent. Du coup, tout ce qui reste, c'est de mettre un lien ou un bouton Back dans SingleFaceSnapComponent pour permettre un retour en arrière facile, mais attention au piège !

<!-- ... -->
<h2>{{ faceSnap.title | uppercase }}</h2>
<a routerLink="/facesnaps">BACK</a>
<!-- ... -->

Avec ces dernières fonctionnalités, votre première application Angular est terminée !

En résumé

  • On récupère les paramètres de la route activée en injectant ActivatedRoute, et via son objet  snapshot.params.

  • Pour naviguer vers une route absolue (et non relative), n'oubliez pas d'ajouter un  /  au début de la route demandée.

Qu'avez-vous appris dans cette partie du cours ?

  • Vous avez centralisé données et logique dans un service que vous avez ensuite injecté dans les components concernés.

  • Vous avez ajouté un module de routing à votre application, et trois routes fonctionnelles.

  • Vous avez mis en place deux systèmes pour que vos utilisateurs puissent changer de route : les routerLinks et le Router.

À la fin du quiz qui suit ce chapitre, vous aurez terminé ce cours d'introduction à Angular ! Vous avez déjà appris beaucoup de choses. Mais ce n'est pas fini ! Après le dernier quiz, je vous partagerai comment poursuivre votre apprentissage du framework Angular... 

Exemple de certificat de réussite
Exemple de certificat de réussite