APIs, langages de transmission de données et requêtes asynchrones
Prévisions météo
Dans ce TP, pour illustrer le recours à un langage de transmission de données (ici, json) et l’utilisation de requêtes asynchrones, nous allons réaliser une petite application de prévision météorologiques.
https://openweathermap.org/API
Pour pouvoir utiliser cette API, il faut un jeton d’identification.
Pour cela, nous allons créer un compte (Create an Account) sur https://home.openweathermap.org/users/sign_in.
Premier essai, téléchargeons et interprétons ce que renvoie https://api.openweathermap.org/data/2.5/weather?q=Nancy,France&appid=??? (mettre le jeton d’identification à la place des ???
.
Nous obtenons un tableau de tableaux dont les index sont des chaînes de caractères (tableau associatif).
Par exemple
{
"sys": {
"sunset": 1372275728,
"country": "FR",
"sunrise": 1372217655
},
"main": {
"temp": 14,
"pressure": 1029,
"temp_max": 14,
"humidity": 71,
"temp_min": 14
},
"coord": {
"lon": 6.2000000000000002,
"lat": 48.683331000000003
},
"wind": {
"speed": 2.6000000000000001,
"var_end": 50,
"deg": 350,
"var_beg": 310
},
"weather": [
{
"id": 802,
"description": "nuages éparses",
"main": "Clouds",
"icon": "03d"
}
],
"base": "global stations",
"dt": 1372233600,
"clouds": {
"all": 48
},
"id": 2990999,
"name": "Nancy",
"cod": 200
}
Firefox permet d’afficher le JSON soit en mode arborescent (lisible, joli), soit en mode texte (RAW).
À l’aide de la documentation, modifier la query string de l’URL de la requête pour avoir des unités “métriques” (degrés Celsius, km/h…) et la langue française dans les réponses du serveur.
Pour commencer dans un fichier
meteop.js
, créer une variable (nommée par exempledonneesMeteo
) contenant ce tableau.Comment peut-on accéder au nom de la ville ? À la température ? À la description du temps ?
Créer une page web
meteop.html
qui affiche une boîte de dialogue de la formeÀ Nancy, la température est de 14 degrés avec nuages épars.
Dans la console, afficher chaque clef du tableau associatif automatiquement (coord, weather, base, …)
Pour actualiser les données sans modifier à la main le javascript, nous allons utiliser la technique jsonp qui consiste à définir la source du fichier json comme un nouveau script et à ajouter un callback à la fonction qui utilise les données.
Fonctionnaliser le javascript pour avoir une fonction
interpreteMeteo
prenant pour argumentdonneesMeteo
.Supprimer la variable globale
donneesMeteo
. Seule doit demeurer dans le fichier js la fonction.Dans la page html, ajouter
<script src="https://api.openweathermap.org/data/2.5/weather?q=Paris,France&appid=???&callback=interpreteMeteo"></script>
et tester cette nouvelle version.
Explications : en ajoutant cette ligne
script
, nous permettons au navigateur de télécharger les données météo courantes, donc d’avoir des données à jour. Pour indiquer à l’interprète javascript ce qu’il doit faire du fichier json téléchargé, nous ajoutons&callback=interpreteMeteo
, le callback donnant la fonction à appliquer aux données obtenues. Cette technique (fichier json dans une balise script adjointe d’un callback) est nommée jsonp pour json padding.
(Optionnel) Créer un formulaire dans lequel entrer un nom de ville et où l’appui sur un bouton indiquera la météo dans la ville en question.
Requêtes asynchrones
Outre jsonp, une autre technique permet de charger des données issues d’un site tiers : l’utilisation de requêtes asynchrones. L’asynchronie signifie que notre script n’a pas se bloquer en attendant le résultat du site distant mais continuer à travailler et repousser le traitement de ce fragment au moment où il arrivera.
La requête se fera à l’aide de fetch
:
var url = "https://api.openweathermap.org/data/2.5/weather?q=Paris,France&appid=???"
var promesse = fetch(url)
var jsonprom = promesse.then(function(r) {return r.json()})
jsonprom.then(interprete)
La ligne 2 crée la requête et stocke la “promesse de résultat” dans la variable promesse. La 3 convertit cette promesse en promesse de json. La ligne 4 indique que quand cette promesse de json sera satisfaite, on la passera à la procédure interprete
.
function interprete (data) {
// traite les données json obtenue par fetch
console.log(data)
}
Note : la syntaxe typique utilisée pour fetch
ne passe pas par des variables intermédiaires (promesse
et jsonprom
) mais enchaîne les then
. De plus la conversion en json utilise souvent la fonctionalisation avec =>
au lieu de function.
fetch(url).then(r => r.json()).then(interprete)
- Dans de nouveaux fichiers
meteo.html
etmeteo.js
, utiliser cette technique pour obtenir les mêmes résultats que dans l’exercice précédent. - Créer un formulaire dans lequel entrer un nom de ville et où l’appui sur un bouton indiquera la météo dans la ville en question.
DOM scripting
Plutôt qu’une alerte, nous voudrions modifier le contenu de la page dynamiquement, c’est-à-dire modifier le code html. On parle de modification du DOM (Document Object Model) ou de DOM-scripting. Le langage javascript, tournant dans les navigateur, dispose de nombreuses fonctions et procédures pour manipuler les documents HTML ou XML.
Fonction ou procédure | Entrée | Sortie | Rôle |
---|---|---|---|
document.createElement(b) |
b : chaine | e : élément HTML | Crée un élément html de balise b |
document.getElementById(i) |
i : chaine | e : élément HTML | Renvoie l’élément de la page ayant pour id i |
document.getElementsByClassName(c) |
c : chaine | t : tableau d’éléments HTML | Renvoie les éléments de la page ayant pour class c |
document.getElementsByTagName(t) |
t : chaine | u : tableau d’éléments HTML | Renvoie les éléments de la page de balise t |
e.setAttribute(x, y) |
e : élément HTML; x, y: chaines | — | Met l’attribut x de l’élément e à la valeur y |
e.appendChild(f) |
e, f : élément HTML | — | Ajoute l’élément f aux fils de e |
Ces diverses fonctions et procédures permettent de créer, trouver et modifier le contenu d’une page HTML programmatiquement.
On remarquera que les deux dernières procédures ont une entrée placée avant le nom de la fonction.
Cette syntaxe est en fait dérivée des dictionnaires, en effet, les éléments HTML sont des dictionnaires ayant des clefs setAttribute
et appendChild
et le contenu des cases ayant ces clefs sont des procédures.
On utilisera également le champ innerHTML
des éléments html pour directement assigner à leur contenu une chaîne de caractères.
À l’aide de ces fonctions, on peut par exemple créer un fichier html quasiment vide et le faire remplir par un script javascript.
Par exemple, considérons le contenu html suivant :
<!doctype html>
<html lang="fr">
<head><meta charset="utf-8" />
<title>DOM Scripting</title>
</head>
<body>
<h1 class="titre"></h1>
<h2 class="titre"></h2>
<div id="contenu"></div>
<script src="remplissage.js"></script>
</body>
Sans exécution de javascript, cette page est vide. En ajoutant le code javascript suivant, la page va se remplir.
var titres, divc, paragraphe, i
= document.getElementsByClassName("titre")
titres for (i = 0; i<titres.length; i = i+1) {
"innerHTML"] = "Nouveau titre " + String(i)
titres[i][
}= document.getElementById("contenu")
divc = document.createElement("p")
paragraphe .setAttribute("class", "vert")
paragraphe"innerHTML"] = "Gallia est omnis divisa in partes tres, quarum unam incolunt Belgae, aliam Aquitani, tertiam qui ipsorum lingua Celtae, nostra Galli appellantur. Hi omnes lingua, institutis, legibus inter se differunt. Gallos ab Aquitanis Garumna flumen, a Belgis Matrona et Sequana dividit."
paragraphe[.appendChild(paragraphe) divc
Et le code html de la page que va afficher le navigateur ressemblera à ce qui suit :
<!DOCTYPE html>
<html lang="fr"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta charset="utf-8">
<title>DOM Scripting</title>
</head>
<body>
<h1 class="titre">Nouveau titre 0</h1>
<h2 class="titre">Nouveau titre 1</h2>
<div id="contenu"><p class="vert">Gallia est omnis divisa in partes tres, quarum unam incolunt Belgae, aliam Aquitani, tertiam qui ipsorum lingua Celtae, nostra Galli appellantur. Hi omnes lingua, institutis, legibus inter se differunt. Gallos ab Aquitanis Garumna flumen, a Belgis Matrona et Sequana dividit.</p></div>
<script src="remplissage.js"></script>
</body></html>
Tester le code ci-dessus. Constater la différence entre le source de la page et ce qu’affiche l’inspecteur html.
Modifier la page de l’exercice précédent pour que les données météorologiques de la ville choisie soient affichées dans un tableau html par exemple comme suit.
Ville Nancy Température 14 Pression 1029 Humidité 74 Vitesse du vent 2.6000002 Direction du vent 350
Autre application
Je souhaite maintenant afficher un classement de D1 de Futsal sur ma page web. Pour cela, je vais utiliser https://cygne.hainry.fr/cours/r209/futsald1.json.
Tester la requête suivante :
var url = "https://cygne.hainry.fr/cours/r209/futsald1.json" fetch(url).then(r => r.json()).then(console.log)
Explorer les résultats de requêtes auprès de ce site.
Créer une page web sur laquelle est affiché le classement de D1. En utilisant les styles, rendre le tableau joli. Vous utiliserez la méthode des requêtes asynchrones.
Vous devriez obtenir un résultat conforme à l’image suivante :
En particulier, faites en sorte que votre équipe préférée apparaisse de façon éclatante.
Créer une page web donnant les informations sur l’équipe de Guingamp. En particulier le calendrier des matches futurs et les résultats des matches passés doit apparaître de façon adéquate.
Modifier cette page web de façon à ce que l’utilisateur puisse choisir son équipe favorite dans une liste déroulante (balise
select
) et voir toutes les informations.
Références
- Jason Lengstorf, JSON: What It Is, How It Works, & How to Use It https://www.copterlabs.com/json-what-it-is-how-it-works-how-to-use-it/
- Mozilla, Using XMLHttpRequest https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest
- Mozillan Using Fetch https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch
- OpenWeatherMap, Free weather data API for developers https://openweathermap.org/API