Cours 1: introduction à Vue.js
Cours 2: Style (Bulma & class-binding)
Cours 3: Client-side routing
Cours 4: Rest, promises, ouverture
On est maintenant capable de
v-bind, v-if, v-on, v-forcomputed properties pour factoriser des calculsQu'est ce qu'il manque à notre application pour être utile ?
⌚ Gérer l'asynchronicité (Promise)
🌐 Aller chercher des vraies données depuis un serveur REST
✏ Modifier les données au sein de l'application
C'est l'objectif de notre séance
Avant de pouvoir effectuer des requêtes réseaux, il va d'abord nous falloir étudier la gestion de l'asynchronicité en JS.
JS fournit un mécanisme pour gérer l'asynchronicité: les promesses
let promise = new Promise(function(resolve, reject) {
// EXECUTER DU CODE QUI PREND DU TEMPS
}); Une promesse = bout de code asynchrone
Une promesse peut être rejetée en cas d'échec...
let promise = new Promise(function(resolve, reject) {
// EXECUTER DU CODE QUI PREND DU TEMPS
// Problème! Je rejette la promesse
reject("There is a problem")
});
... et résolue (avec un résultat) en cas de succès
let promise = new Promise(function(resolve, reject) {
// EXECUTER DU CODE QUI PREND DU TEMPS
// Succès ! Je resolve avec le result
var result = { first_name: 'Paul', last_name: 'Mc Cartney'}
resolve(result);
});
On parle de fonction/méthode asynchrone pour désigner une méthode retournant une promesse
function asyncFunction() {
return new Promise(function(resolve, reject) {
// EXECUTER DU CODE QUI PREND DU TEMPS
// Succès ! Je resolve avec le result
var result = { first_name: 'Paul', last_name: 'Mc Cartney'}
resolve(result);
});
}
L'appel d'une fonction asynchrone ne bloque pas le fil d'exécution contrairement à une méthode synchrone
L'appel d'une fonction asynchrone ne bloque pas le fil d'exécution contrairement à une méthode synchrone
console.log("coucou");
var result = asyncFunction();
console.log("Tout de suite appelé");
// Attention ici asyncFunction() n'a peut pas terminé son exécution
Quel est le type de result ?
Quel est le type de result ?
C'est une promesse, qui pour l'instant n'est pas résolue ni rejetée (on dit qu'elle est pending)
Comment exécuter du code lorsque la promesse est résolue/rejetée ?
Avec la méthode then
asyncFunction().then(fonctionEnCasDeResolution, fonctionEnCasDechec)
(et éventuellement catch)
asyncFunction()
.then(fonctionEnCasDeResolution)
.catch(fonctionEnCasDechec)
Comment exécuter du code lorsque la promesse est résolue/rejetée ?
asyncFunction()
.then(fonctionEnCasDeResolution)
.catch(fonctionEnCasDechec)
asyncFunction()
.then(result => {
// Ici la promesse est résolue, on a accès au résultat
console.log("Success ! ", result)
})
.catch(failure => {
// Ici la promesse est rejetée, on a accès à la cause d'échec
console.err("Failure :( ", failure)
})
)
main.jsasyncFailIfMust(mustFail) qui est rejetée si mustFail vaut vrai et retourne "success" dans le cas contrairesetTimeout() pour faire en sorte que asyncFailIfMust mette 3 secondes à s'exécuter, et ajouter des logs avant/après l'appel, pour obtenir le résultat suivant:
On peut effectuer de l'orchestration de promesses : comme les chaîner les unes à la suite des autres...
...lancer plusieurs tâches asynchrones et être notifié quand elles sont toutes résolues
Ce n'est pas l'objet du cours, mais vous pouvez regarder la doc de Promise.all par exemple
Je ne suis personnellement pas fan de la syntaxe pour des opérations simples (inutilement verbeux).
On peut aussi attendre la résolution de la promess grâce au mot-clé await
try {
var result = await asyncFunction();
console.log("Grâce à await on a attend la fin de l'execution");
} catch (reject) {
console.error("Promesse rejetée")
}
try {
var result = await asyncFunction();
console.log("Grâce à await on a attend la fin de l'execution");
} catch (reject) {
console.error("Promesse rejetée")
}
Les développeurs se sont dit qu'en utilisant await à tord et à travers, on risquait de bloquer le navigateur
Il n'est donc possible d'utiliser await que dans une fonction explicitement définie comme async
Il n'est donc possible d'utiliser await que dans une fonction explicitement définie comme async
async someFunction() {
try {
var result = await asyncFunction();
console.log("Grâce à await on a attend la fin de l'execution");
} catch (reject) {
console.error("Promesse rejetée")
}
}
main.js
On est maintenant capable
On veut faire en sorte que notre application Vue soit capable d'effectuer des requêtes REST (pour interragir avec un serveur).
Tous les navigateurs récents sont munis d'une API native, fetch, qui permet d'effectuer des requêtes HTTP vers un serveur REST.
fetch('http://someserver.com/api/someroute')
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
Doc complète disponible ici
Il existe également une libraire standalone js, Axios, qui fournit des fonctionnalités similiares à fetch
axios.get('http://someserver.com/api/someroute')
.then(response => {
console.log(response.data)
})
.catch(error => {
console.log(error)
})
}
Doc complète disponible ici
Chaque libraire dispose de ses avantages, les deux solutions se valent globalement (voir comparatif ici)
fetch est natif (dispo via le navigateur rien à installer), Axios gère plus facilement la compatiblité avec les vieux navigateurs (faisable avec des polyfills sur fetch) et fournit du sucre syntaxique
On partira sur Axios pour notre projet, mais fetch reste parfaitement valable.
On ne va voir qu'une infime portion des fonctionnalités d'Axios, qui permet notamment
axios.get('http://someserver.com/api/someroute')
.then(response => {
console.log(response.data)
})
.catch(error => {
console.log(error)
})
}
Bon, reste à savoir quand appeler ce code...
Au chargement du composant ComposterList ?
Au chargement du composant ComposterList ?
Tous les composants Vue ont un cycle de vie (créé, monté, affiché, détruit...)
À chaque changement d'état, une méthode est appelée (lifecycle hooks), dans laquelle on peut brancher du comportement
Il existe de nombreux hooks (voir liste complète ici), par exemple:
beforeCreate(): au moment où vue commence à créer le composantmounted(): le composant est prêt à être affichéupdated(): à chaque fois que le DOM est rafraîchi suite à un changement de props/datamounted(): le composant est prêt à être affiché
import axios from "axios";
export default {
name: "MyComponent",
data() {
return {
myList: new Array()
};
},
mounted() {
axios
.get("http://someserver.com/api/someroute")
.then((response) => {
this.myList = response.data
})
.catch((error) => {
console.log(error);
});
},
};
ComposterList, utilisez axios pour récupérer la liste des composteurs
(via cette url)
Composter pour afficher les informations à votre disposition:
Axios fonctionne exactement pareil pour les requêtes POST (envoi d'image, de données..)
Dans un "vrai" projet, tout le code purement logique serait extrait dans un service (SOC)
On est maintenant capable de
v-bind, v-if, v-on, v-forQu'est ce qu'il manque à notre application pour être utile ?
🧐 Quelques notions Vue (events...)
✅ Comment Debugger/Tester notre app
🦋 Comment déployer notre app (sur nos builds, sur serveur, sur mobile)
- Vos retours (trop dur/facile rapide/lent)
- Ma porte reste ouverte (par mail et/ou sur discoord et/ou sur twitter)