Aller au contenu principal

28-8 Ajout de l'action update au contrôleur de projets

Maintenant qu'il est possible de créer des projets en mémoire (sans BD), il serait logique de pouvoir les modifier.

Créer un DTO pour la mise à jour

Pour la mise à jour, nous ne pouvons pas réutiliser directement le DTO de création. Dans un premier temps, le fait d'utiliser CreateProjetDto serait étrange dans un contexte de mise à jour.

Ensuite, lors d'une mise à jour, normalement ce ne sont pas tous les champs qui sont requis. En effet, on pourrait faire une mise à jour partielle de seulement quelques attributs.

Toutefois, Nest pour nous aider afin d'éviter les répétitions en créant un nouveau type calqué sur CreateProjetDto.

Pour créer un type calqué sur CreateprojetDto, mais avec toutes ses propriétés optionnelles, il est possible d'utiliser PartialType de la librairie mapped-types.

  1. Installer la dépendance mapped-types de NestJS via npm

    npm install @nestjs/mapped-types
  2. Créez un fichier update-projet.dto.ts sous src/projets/dto

    src/projets/dto/update-projet.dto.ts
    export class UpdateProjetDto {}
  3. Faites hériter UpdateProjetDto de PartialType(CreateProjetDto)

    src/projets/dto/update-projet.dto.ts
    import { CreateProjetDto } from './create-projet.dto';
    import { PartialType } from '@nestjs/mapped-types';

    export class UpdateProjetDto extends PartialType(CreateProjetDto) {}
    info

    L'utilisation de PartialType() retourne exactement la même classe que CreateProjetDto, mais avec tous ses attributs optionnels. De cette façon, nous n'avons pas à redéfinir une classe quasi identique une deuxième fois!

    C'est l'équivalent d'avoir défini le DTO suivant (tous les attributs sont optionnels):

    export class UpdateProjetDto {
    nom?: string;
    description?: string;
    image_url?: string;
    }

Ajouter la fonction modifier() au service ProjetsService

  1. La fonction de modification du service acceptera en paramètre le id du projet à modifier et un DTO de mise à jour.

    src/projets/projets.service.ts
    modifier(id: number, updateProjetDto: UpdateProjetDto) {

    }
  2. Ensuite, on peut trouver le projet à modifier dans la liste en mémoire, ainsi que son identifiant.

    src/projets/projets.service.ts
    modifier(id: number, updateProjetDto: UpdateProjetDto) {
    const projetIndex = this.projets.findIndex((projet) => {
    return projet.id === id;
    });
    const projet = this.projets[projetIndex];
    }
    info

    Pour remplacer le projet, lors de la modification, nous aurons besoin de son index dans le tableau, c'est pourquoi ici on utilise findIndex plutôt que simplement find.

  3. Finalement, il est possible de modifier le projet et de remplacer l'ancienne version par la nouvelle.

    src/projets/projets.service.ts
    modifier(id: number, updateProjetDto: UpdateProjetDto) {
    const projetIndex = this.projets.findIndex((projet) => {
    return projet.id === id;
    });
    const projet = this.projets[projetIndex];

    if (projet) {
    projet.nom = updateProjetDto.nom || projet.nom;
    projet.description = updateProjetDto.description || projet.description;
    projet.date_modification = new Date().toJSON();
    this.projets.splice(projetIndex, 1, projet);
    }

    return projet;
    }
    À propos de l'utilisation de || lors de l'assignation

    L'utilisation de la formulation projet.nom = updateProjetDto.nom || projet.nom; fait en sorte d'assigner la première valeur de droite (updateProjetDto.nom) si elle est présente (pas null ou undefined), sinon la deuxième valeur est utilisée (projet.nom). C'est le principe d'utiliser || lors d'une assignation.

    À propos de la fonction splice

    La fonction splice sur un tableau en javascript permet de remplacer un ou plusieurs éléments à partir d'un certain index.

    • projetIndex: l'index à laquel remplacer un élément
    • 1: le nombre d'éléments à remplacer
    • projet: le ou les éléments remplaçants

Ajouter l'action update au contrôleur ProjetsController

Le contrôleur est très simple, puisqu'il récupère le @Body (contenu de la requête) et l'assigne à updateProjetDto.

On utilise la méthode @Patch ici puisqu'on permet les mises à jour partielles.

src/projets/projets.controller.ts
@Patch(':id')
update(@Param('id') id: string, @Body() updateProjetDto: UpdateProjetDto) {
const projet = this.projetsService.obtenir(+id);

if (!projet) throw new NotFoundException();

return this.projetsService.modifier(+id, updateProjetDto);
}
info

On vérifie premièrement que le projet à modifier existe. Si ce n'est pas le cas, une erreur 404 est retournée.

Test Postman

Testez via Postman à l'aide d'une requête PATCH vers un projet spécifique:

  • Type: PATCH
  • URL: http://localhost:3000/projets/1
  • Body: raw / JSON
    {
    "nom": "Projet modifié!"
    }

Vous devriez recevoir comme réponse quelque chose ressemblant à ceci:

{
"id": 1,
"nom": "Projet modifié!",
"description": "Organiser le LAN Party",
"image_url": "https://i.imgur.com/Y5nZ4Qe.jpg",
"date_creation": "2023-10-11T14:38:57.981Z",
"date_modification": "2023-10-11T14:41:15.753Z"
}