Défi
On souhaite mettre à disposition de l'administrateur de notre site une page lui permettant de récupérer l'ensemble des adresses françaises correspondant à sa recherche.
On dispose du code HTML et JavaScript suivant :
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<label for="address">Adresse à rechercher</label>
<input type="text" name="address" id="address">
<button onclick="manageResearch()">Rechercher</button>
<div>
<ul id="results">
</ul>
</div>
<script src="script.js"></script>
</body>
</html>
function manageResearch () {
console.log('J\'ai été déclenchée')
}
L'accès à cette API doit être restreint au possible. Notre administrateur a beau être déjà connecté au site web, on souhaite qu'il décline de nouveau son identité. On souhaite également vérifier qu'il n'est pas un robot en lui faisant effectuer une opération mathématique.
Question
Écrivez les promesses suivantes au sein de fonctions dédiées.
Une première promesse demandera à l'utilisateur son nom : s'il répond
admin
, la promesse sera résolue, sinon elle sera rejetéeUne seconde promesse demandera à l'utilisateur combien font 6 x 7 : s'il répond 42, la promesse sera résolue, sinon elle sera rejetée
Ces deux promesses devront toutes les deux être résolues au sein de la fonction manageResearch
. Si elles sont toutes les deux validées, un message indiquant que l'utilisateur peut accéder à l'application sera affiché en console, sinon un message indiquant "Accès refusé" sera affiché.
La fonction manageResearch
est déclenchée lorsque l'on appuie sur le bouton "Rechercher".
Solution
function askUsername() {
return prompt('Quel est votre nom d\'utilisateur ?')
}
function askMathOperation() {
return prompt('Combien font 6 x 7')
}
function success() {
console.log('Vous pouvez accéder à l\'application')
}
function error() {
console.log('Accès refusé')
}
function checkUsername() {
return new Promise((resolve, reject) => {
let username = askUsername()
if ('admin' === username) {
resolve()
} else {
reject()
}
})
}
function checkIfIsBot() {
return new Promise((resolve, reject) => {
let result = askMathOperation()
if (42 === parseInt(result)) {
resolve()
} else {
reject()
}
})
}
function manageResearch () {
Promise.all([checkUsername(), checkIfIsBot()]).then(success, error)
}
Pour effectuer une recherche, on se basera sur l'API suivante : https://geo.api.gouv.fr/adresse.
Si l'on souhaite récupérer les résultats pour l'adresse "8 bd du port", on appellera l'URL suivante : https://api-adresse.data.gouv.fr/search/?q=8+bd+du+port.
En JavaScript, il est possible d'implémenter une URL avec l'objet URL
, qui dispose d'une propriété search
. Il est possible de définir des paramètres à une requête GET
au moyen de l'objet URLSearchParams
.
Question
Procédons par étapes, dans un premier temps :
Déclarez une constante
url
contenant l'adressehttps://api-adresse.data.gouv.fr/search
Au sein d'une nouvelle fonction appelée
searchAddress
, initialisez votre URL en définissant un nouvel objet de typeURLSearchParam
. Celui-ci contiendra une propriétéq
dont la valeur correspondra à la valeur de l'input#address
Vous pourrez vérifier le contenu de l'objet construit grâce à l'instruction suivante : console.log(url.href);
.
La fonction searchAddress
sera quant à elle appelée au sein de la fonction success
précédemment déclarée.
Solution
const url = new URL('https://api-adresse.data.gouv.fr/search')
// ... //
function success() {
console.log('Vous pouvez accéder à l\'application')
searchAddress()
}
function searchAddress() {
let params = {q: document.getElementById("address").value}
url.search = new URLSearchParams(params).toString();
console.log(url.href);
}
Question
Vous disposez de la fonction suivante, permettant d'afficher les résultats sur votre page.
À l'aide de l'API Fetch, appelez l'URL que vous avez construite au sein de la fonction searchAddress
et appelez la fonction dont vous disposez en cas de succès.
Vous traiterez l'affichage des erreurs en les affichant en console.
La méthode createTextNode() crée un nœud de texte avec le texte spécifié.
function fillResults(data) {
let list = document.getElementById('results')
list.innerHTML = ''
if(undefined !== data.features) {
data.features.forEach(function(element) {
let li = document.createElement('li')
li.appendChild(document.createTextNode(element.properties.label))
list.appendChild(li)
});
}
}
Solution
Voici comment la fonction searchAddress
a dû être complétée :
function searchAddress() {
let params = {q: document.getElementById("address").value}
url.search = new URLSearchParams(params).toString();
fetch(url)
.then((response) => {
if(response.ok){
return response.json()
} else {
console.error("Erreur réponse : " + response.status)
}
})
.then((data) => {
fillResults(data)
})
.catch((error) => console.error(error)) //Traitement de l'erreur dans l'appel
}
Voici également le script dans sa globalité :
const url = new URL('https://api-adresse.data.gouv.fr/search')
function askUsername() {
return prompt('Quel est votre nom d\'utilisateur ?')
}
function askMathOperation() {
return prompt('Combien font 6 x 7')
}
function success() {
console.log('Vous pouvez accéder à l\'application')
searchAddress()
}
function error() {
console.log('Accès refusé')
}
function checkUsername() {
return new Promise((resolve, reject) => {
let username = askUsername()
if ('admin' === username) {
resolve()
} else {
reject()
}
})
}
function checkIfIsBot() {
return new Promise((resolve, reject) => {
let result = askMathOperation()
if (42 === parseInt(result)) {
resolve()
} else {
reject()
}
})
}
function manageResearch () {
Promise.all([checkUsername(), checkIfIsBot()]).then(success, error)
}
function searchAddress() {
let params = {q: document.getElementById("address").value}
url.search = new URLSearchParams(params).toString();
fetch(url)
.then((response) => {
if(response.ok){
return response.json()
} else {
console.error("Erreur réponse : " + response.status)
}
})
.then((data) => {
fillResults(data)
})
.catch((error) => console.error(error)) //Traitement de l'erreur dans l'appel
}
function fillResults(data) {
let list = document.getElementById('results')
list.innerHTML = ''
if(undefined !== data.features) {
data.features.forEach(function(element) {
let li = document.createElement('li')
li.appendChild(document.createTextNode(element.properties.label))
list.appendChild(li)
});
}
}