Aller au contenu principal

35-4 Obtenir une liste d'issues

Ajouter des données de test

Dans un premier temps, ajoutez des données de test à votre table issues Imgur

Récupérer projetId dans la fonction findAll() du contrôleur

danger

Remarquez que la fonction du service s'appelle findAll() plutôt que obtenirTous(). C'est que nous avons utilisé le générateur de ressource de NestJS pour générer le tout et ce dernier nomme les fonctions en anglais.

Pour votre projet, vous pouvez utiliser ce qui vous convient, l'important est d'être constant dans TOUS vos services.

Ensuite, même si projetId est défini au niveau de la route principale du contrôleur IssuesController, on peut tout de même le récupérer via @Param et l'assigner à un paramètre de la fonction.

src/issues/issues.controller.ts
@Get()
findAll(@Param('projetId') projetId: string) {
return this.issuesService.findAll(+projetId);
}
info

La portion +projetId sera en erreur puisque le service n'est pas configuré pour accepter un paramètre. Nous allons y remédier à la prochaine étape.

Obtenir les issues dans IssuesService

  1. Modifier la fonction findAll du service pour accepter en paramètre un id de projet
    src/issues/issues.service.ts
    findAll(projetId: number) {
    return `This action returns all issues`;
    }
  2. Obtenir les issues du projet. Une première approche est de récupérer le projet associé à projetId et ensuite de récupérer la liste d'issues via projet.issues
    src/issues/issues.service.ts
    async findAll(projetId: number) {
    const projet = await Projet.findOneOrFail({
    where: {
    id: projetId,
    },
    });
    return projet.issues;
    }

### Tester via Postman

Vous pouvez faire une requête `GET http://localhost:3000/projets/1/issues`, mais cela ne retourne rien ☹️

Au fond, c'est que la requête pour obtenir le serveur ne retourne pas les relations:

```sql
SELECT "Projet"."id" AS "Projet_id", "Projet"."nom" AS "Projet_nom", "Projet"."description" AS "Projet_description", "Projet"."imageUrl" AS "Projet_imageUrl", "Projet"."date_creation" AS "Projet_date_creation", "Projet"."date_modification" AS "Projet_date_modification" FROM "projets" "Projet" WHERE ("Projet"."id" = $1) LIMIT 1 -- PARAMETERS: [1]

Donc, appeler projet.issues ne retourne rien puisque le tableau est vide (même s'il y a des issues dans la base de données).

Charger les relations via une requête TypeORM

Par souci d'efficacité, TypeORM ne charge pas les relations, sauf si on le mentionne explicitement. Pour mentionner les relations à charger, on ajoute un paramètre relations aux options de find/findOne.

src/issues/issues.service.ts
async findAll(projetId: number) {
const projet = await Projet.findOneOrFail({
where: {
id: projetId,
},
relations: {
issues: true,
}
});
return projet.issues;
}

Tester via Postman

Effectuez la même requête, soit GET http://localhost:3000/projets/1/issues, et cela retourne maintenant la bonne liste!

De plus, remarquez que les relations sont chargées via un LEFT JOIN:

SELECT "Projet"."id" AS "Projet_id", "Projet"."nom" AS "Projet_nom", "Projet"."description" AS "Projet_description", "Projet"."imageUrl" AS "Projet_imageUrl", "Projet"."date_creation" AS "Projet_date_creation", "Projet"."date_modification" AS "Projet_date_modification", "Projet__Projet_issues"."id" AS "Projet__Projet_issues_id", "Projet__Projet_issues"."titre" AS "Projet__Projet_issues_titre", "Projet__Projet_issues"."contenu" AS "Projet__Projet_issues_contenu", "Projet__Projet_issues"."imageUrl" AS "Projet__Projet_issues_imageUrl", "Projet__Projet_issues"."statut" AS "Projet__Projet_issues_statut", "Projet__Projet_issues"."date_creation" AS "Projet__Projet_issues_date_creation", "Projet__Projet_issues"."date_modification" AS "Projet__Projet_issues_date_modification", "Projet__Projet_issues"."projetId" AS "Projet__Projet_issues_projetId" FROM "projets" "Projet" LEFT JOIN "issues" "Projet__Projet_issues" ON "Projet__Projet_issues"."projetId"="Projet"."id" WHERE ( ("Projet"."id" = $1) ) AND ( "Projet"."id" IN (1) ) -- PARAMETERS: [1]

Requête alternative sur Issue directement

On aurait pu aussi faire une requête where directement sur la classe Issue et retourner ce résultat.

src/issues/issues.service.ts
async findAll(projetId: number) {
return Issue.find({
where: {
projet: {
id: projetId
}
}
});
}

Ce qui donne le même résultat et génère la requête suivante:

SELECT "Issue"."id" AS "Issue_id", "Issue"."titre" AS "Issue_titre", "Issue"."contenu" AS "Issue_contenu", "Issue"."imageUrl" AS "Issue_imageUrl", "Issue"."statut" AS "Issue_statut", "Issue"."date_creation" AS "Issue_date_creation", "Issue"."date_modification" AS "Issue_date_modification", "Issue"."projetId" AS "Issue_projetId" FROM "issues" "Issue" LEFT JOIN "projets" "Issue__Issue_projet" ON "Issue__Issue_projet"."id"="Issue"."projetId" WHERE ("Issue__Issue_projet"."id" = $1) -- PARAMETERS: [1]