API Fetch
L'API JavaScript Fetch fournit une interface pour récupérer, de manière asynchrone, des ressources sur un réseau. Son 1er argument (obligatoire) est l'URL offrant la ressource à récupérer. Le 2nd argument est optionnel mais permet de personnaliser la requête (ou d'effectuer les réglages sur le corps de la requête).
Le rendu de cette fonction "fetch" est un objet (nommé : promesse) qui a 3 états :
pending : en cours
fulfilled : terminé (sans erreur)
rejected : rejeté
Dans les extraits de code ci-dessous fetch est utilisée avec son seul argument obligatoire, une URL :
fetch('https://code.dhumbert.info/json/demo.json')
fetch("http://localhost/crud.php?op=create&studentName=Pierre&course=informatique");
Dans le 1er extrait, l'URL n'a pas de paramètre. Dans le second, elle en a 3 qui sont dans l'ordre :
"op" de valeur "create" ;
"studentName" de valeur "Pierre" ;
"course" de valeur "informatique".
Pour ne pas afficher les paramètres de l'URL dans la requête, fetch pourra être utilisée avec un argument optionnel de réglage décrivant la requête comme dans l'exemple ci-après.
fetch(
"http://localhost/crud.php",
{
method: "POST",
headers: {
Accept: 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
'op': 'create',
'studentName' :'Pierre",
'course': 'informatique',
})
}
)
Dans l'extrait de code ci-dessus, 3 propriétés caractérisent le réglage :
- method :
- headers :
- body : contient les "variables" de la requête (mise au format JSON dans cet exemple)
Lire ce billet pour en savoir plus sur ces réglages
La promesse (le rendu de fetch) est un objet qui possède 2 méthodes :
- "then" qui est, le plus souvent, utilisée avec pour paramètre, une fonction fléchée dont l'argument est la réponse à la requête fetch ;
- "catch" qui permet la gestion des erreurs (NB : lorsqu'une erreur est détectée, "then" est ignoré).
Gestion de la réponse :
Le fichier à l'adresse https://code.dhumbert.info/json/demo.json est le texte au format JSON suivant :
{
"count":2,
"results":[
{
"name":"bulbasaur",
"url":"https://pokeapi.co/api/v2/pokemon/1/"
},
{
"name":"ivysaur",
"url":"https://pokeapi.co/api/v2/pokemon/2/"
}
]
}
Dans le code ci-dessous :
const [data, setData] = useState([]);
fetch('https://code.dhumbert.info/json/demo.json')
.then( response => response.json() )
.then( responseJson=> setData(responseJson.results) )
.catch( error => console.error(error) );
La méthode "then" est appliquée une 1ère fois pour convertir la réponse au format JSON puis une 2ème fois sur l'objet converti pour en extraire la valeur de l'élément "results" et le stocker dans la variable d'état "data".
En résumé :
"fetch" rends une promesse que j'utiliserai dans l'argument de ma 1ère fonction fléchée sous l'identifiant "response" ;
"then" rends une nouvelle promesse que j'utilise dans l'argument de ma 2ème fonction fléchée sous l'identifiant "responseJSON" ;
"then" (le 2ème) rends une nouvelle promesse dont on extrait la valeur d'un élément (ici un tableau d'objet).
Voir la documentation https://developer.mozilla.org/fr/docs/Web/JavaScript/Guide/Using_promises et le billet sur les variables d'état https://dhumbert.info/dev/react/state
Le code ci-dessous est équivalent au précédent mais absolument illisible et donc peu facile à maintenir.
const [data, setData] = useState([]);
fetch('https://code.dhumbert.info/json/demo.json')
.then(u => u.json())
.then(u => setData(u.results) )
.catch(u =>console.error(u));
Le code ci-dessous est utilise la syntaxe complète ( ie : non simplifiée) :
const [data, setData] = useState([]);
fetch('https://code.dhumbert.info/json/demo.json')
.then ( (response) => { response.json() })
.then( (responseJson)=> {setData(responseJson.results) } )
.catch( (error) => {console.error(error)} );