5. Relier nos données et les routes d’Express

On a eu l’impression d’avoir bien avancé, en ajoutant nos propres pokémons dans l’API Rest. Malheureusement, comme souvent en informatique, cela ne s’est pas passé comme nous l’aurions voulu. Nous sommes tombés sur une vilaine erreur :

TypeError: Cannot read property 'name' of undefined

Par rapport au code de notre endpoint, cela semble signifier que la variable pokemon à la ligne 6 ne soit pas correctement retournée par la méthode find, toujours dans le fichier app.js :

// ...
 
app.get('/api/pokemons/:id', (req, res) => {
  const id = req.params.id
  // Est-ce que pokemon serait indéfinie ci-dessous ?
  const pokemon = pokemons.find(pokemon => pokemon.id === id)
  res.send(`Vous avez demandé le pokémon ${pokemon.name}.`) // <- Erreur ici !
})
 
// ...

Bon, il semble que la méthode find ne renvoie rien, puisque l’erreur a lieu juste après. Si on s’intéresse de plus près à cette méthode find, on remarque que la valeur de retour est soit « La valeur du premier élément du tableau qui valide la condition passée en paramètre, sinon undefined.« 

Pourtant il y a bien un pokémon avec l’identifiant 1 dans notre liste de pokémons, et c’est Bulbizzare !

Au secours, à l’aide ! Je ne comprends pas pourquoi ça ne fonctionne pas ?!  🤯

Allez, on va regarder ça ensemble parce que ce n’est pas si simple à trouver. En fait il y a deux choses à noter :

  • Le routeur d’Express passe les paramètre sous forme de chaîne de caractère, systématiquement. Ainsi, le paramètre 1 devient la chaîne de caractère « 1 », dans le code de notre point de terminaison.
  • L’identifiant de notre liste de pokémons est un nombre, comme on peut le vérifier dans le fichier mock-pokemon.ts.

En prenant en compte ses deux considérations, et bien à la ligne 6 lorsqu’on exécute la condition :

pokemon.id === id

Cela revient en fait à comparer les deux valeurs suivantes :

"1" === 1 // Cette condition revoie la valeur 'false'.

Or cette condition renverra la valeur false !

Du coup, la méthode find ne renverra jamais aucun pokémon…

Bon, au moins on a trouvé l’erreur, ce qui est souvent le plus dur lorsqu’on fait face à un problème pour la première fois. Maintenant, il reste à le corriger.

Cependant, la solution semble toute trouvée, il faut convertir la chaîne de caractère représentant l’identifiant d’un pokémon en un nombre, comme nous le voulions initialement. Après tout, c’est Express qui a converti tout cela en chaîne de caractères !

Pour cela, on va utiliser la méthode parseInt de JavaScript, qui permet de convertir une chaîne de caractère en un nombre équivalent :

// ...
 
app.get('/api/pokemons/:id', (req, res) => {
  const id = parseInt(req.params.id) // id est maintenant un nombre !
  const pokemon = pokemons.find(pokemon => pokemon.id === id)
  res.send(`Vous avez demandé le pokémon ${pokemon.name}.`)
})
 
// ...

Comme vous pouvez le voir à la ligne 4, on passe le paramètre « id » transmis par le routeur d’Express, directement en paramètre de la méthode parseInt. Ainsi, on se retrouve en sortie avec la valeur 1, et non « 1 ».

Maintenant, retournez dans votre navigateur pour tester tout cela, à l’adresse « localhost:3000/api/pokemons/1 » :

Cela semble fonctionner parfaitement, plus aucune erreur en vue ! 🎉

Et en prime, cela fonctionne avec n’importe quel identifiant valide pour un pokémon :

Et voilà ! Franchement, nous pouvons être fiers de nous là. Nous avons complètement relié le routeur d’Express à nos propres données de pokémons.

Vous êtes donc largement prêt à affronter l’exercice qui vous attend dans l’étape suivante, non ? 😇

Comme vous avez pu le constater, il est compliqué de trouver la cause des erreurs côté serveur, car nous n’avons pas un outil dédié à cela, comme c’est le cas avec la console du navigateur. Mais nous aborderons calmement ce sujet plus tard, dans un chapitre dédié.