Master 2 INTENSE: Frameworks JavaScript et Server-Side JavaScript BD NoSQL Cloud etc.

De $1

Table des matières
  1. 1. Introduction
  2. 2. Séance 1 : état des lieux du développement Web, intro à VueJS
    1. 2.1. DOM or not to DOM ?
      1. 2.1.1. Ecriture en live coding d'un gestionnaire de todos :
    2. 2.2. Suite de l'étude de VueJS
      1. 2.2.1. Développer en mode "CLI" avec un environnement de build/testy
  3. 3. Séance 2: suite VueJS, intro à React
    1. 3.1. Avoir une vue de l'écosystème JavaScript (sites vus en cours)
    2. 3.2. Comment faire de belles interfaces Web avec VueJS ?
    3. 3.3. Introduction à React
      1. 3.3.1. Exercices d'introduction, dans une IDE en ligne
      2. 3.3.2. Exercice à faire en vous aidant des exercices précédents:
      3. 3.3.3. Exercices avec un environnement "CLI"
  4. 4. Séance 3: Utilisation de FireBase, une base de données basée cloud synchronisée
  5. 5. Séance 4 - présentation de NodeJS et premiers exercices simples
    1. 5.1. Ressource : des MOOCS!
    2. 5.2. Outils à installer
    3. 5.3. TP - routage avec le module ExpressJS, Web Services RESTFUL
  6. 6. TP - MongoDB
    1. 6.1. 1 - Installer MongoDB sur votre machine
    2. 6.2. 2 - Créer et peupler une collection par défaut (avec un dataset issu du tutorial MongoDB officiel)
    3. 6.3. 3 - Installer un outil d'administration sympa
    4. 6.4. 4 - Ouvrir 3T STudio et voir la collection que l'on vient d'importer
    5. 6.5. 5 - Installer le driver MongoDB pour NodeJS
    6. 6.6. 6 - Tester des requêtes CRUD avec NodeJS et express   
  7. 7. Suite de l'étude de Réact : liaison avec Node/MongoDB
    1. 7.1. Ressources externes :
    2. 7.2. Travailler avec les restaurants et la base MongoDB
    3. 7.3. Si vous voulez ajouter le support "cross domain" à votre projet node/MongoDB
    4. 7.4. Travail à faire (à rendre et noté) : refaire l'application VueJS qui fait le CRUD sur les restaurants, mais en React
  8. 8. Premiers pas avec Angular (4/5)
    1. 8.1. 1 : création d'une application "squelette"
    2. 8.2. 2 : affichage d'une liste d'éléments
    3. 8.3. 3 : création d'un nouveau composant
    4. 8.4. 4 : définition d'un événement qui sera envoyé du composant "fils" vers le composant "père"
    5. 8.5. 5 : binding bi-directionnel avec [(ngModel)]="nom"
    6. 8.6. 6 : refaire l'exemple des hobbies complet, mais en angular
  9. 9. Démarrage du mini projet
  10. 10. Hébergement sur HEROKU.COM
      1. 10.1.1. Exemples d'applications prêtes à déployer sur Heroku (regardez les README.txt pour les explications)

Version de 19:14, 16 Avr 2024

cette version.

Revenir à liste des archives.

Voir la version actuelle

  1. 1. Introduction
  2. 2. Séance 1 : état des lieux du développement Web, intro à VueJS
    1. 2.1. DOM or not to DOM ?
      1. 2.1.1. Ecriture en live coding d'un gestionnaire de todos :
    2. 2.2. Suite de l'étude de VueJS
      1. 2.2.1. Développer en mode "CLI" avec un environnement de build/testy
  3. 3. Séance 2: suite VueJS, intro à React
    1. 3.1. Avoir une vue de l'écosystème JavaScript (sites vus en cours)
    2. 3.2. Comment faire de belles interfaces Web avec VueJS ?
    3. 3.3. Introduction à React
      1. 3.3.1. Exercices d'introduction, dans une IDE en ligne
      2. 3.3.2. Exercice à faire en vous aidant des exercices précédents:
      3. 3.3.3. Exercices avec un environnement "CLI"
  4. 4. Séance 3: Utilisation de FireBase, une base de données basée cloud synchronisée
  5. 5. Séance 4 - présentation de NodeJS et premiers exercices simples
    1. 5.1. Ressource : des MOOCS!
    2. 5.2. Outils à installer
    3. 5.3. TP - routage avec le module ExpressJS, Web Services RESTFUL
  6. 6. TP - MongoDB
    1. 6.1. 1 - Installer MongoDB sur votre machine
    2. 6.2. 2 - Créer et peupler une collection par défaut (avec un dataset issu du tutorial MongoDB officiel)
    3. 6.3. 3 - Installer un outil d'administration sympa
    4. 6.4. 4 - Ouvrir 3T STudio et voir la collection que l'on vient d'importer
    5. 6.5. 5 - Installer le driver MongoDB pour NodeJS
    6. 6.6. 6 - Tester des requêtes CRUD avec NodeJS et express   
  7. 7. Suite de l'étude de Réact : liaison avec Node/MongoDB
    1. 7.1. Ressources externes :
    2. 7.2. Travailler avec les restaurants et la base MongoDB
    3. 7.3. Si vous voulez ajouter le support "cross domain" à votre projet node/MongoDB
    4. 7.4. Travail à faire (à rendre et noté) : refaire l'application VueJS qui fait le CRUD sur les restaurants, mais en React
  8. 8. Premiers pas avec Angular (4/5)
    1. 8.1. 1 : création d'une application "squelette"
    2. 8.2. 2 : affichage d'une liste d'éléments
    3. 8.3. 3 : création d'un nouveau composant
    4. 8.4. 4 : définition d'un événement qui sera envoyé du composant "fils" vers le composant "père"
    5. 8.5. 5 : binding bi-directionnel avec [(ngModel)]="nom"
    6. 8.6. 6 : refaire l'exemple des hobbies complet, mais en angular
  9. 9. Démarrage du mini projet
  10. 10. Hébergement sur HEROKU.COM
      1. 10.1.1. Exemples d'applications prêtes à déployer sur Heroku (regardez les README.txt pour les explications)

Introduction

Dans ce cours nous allons voir plusieurs aspects du développement Web Moderne :

  • Frameworks front end VueJS, React, Angular
  • Server Side JavaScript : NodeJS et principaux packages
  • Utilisation de la BD NoSQL MongoDB
  • Utilisation de base de données dans le cloud adaptées aux applis mobiles (syncrhonisées) comme FireBase
  • Hébergement dans le cloud, authentification via des services en ligne comme Oauth2
  • Développement en mode PAAS (Platform As A Service)

A faire : si vous êtes sous windows, installer un bon terminal en ligne de commande comme  http://cmder.net/ ou autre (github bash, etc.) si je vous vois avec une fenêtre DOS basique vous allez m'entendre !

Séance 1 : état des lieux du développement Web, intro à VueJS

DOM or not to DOM ?

Ecriture en live coding d'un gestionnaire de todos :

Nous allons comparer plusieurs versions:

  1. Pur JavaScript + DOM API : http://jsbin.com/gaqugic/edit
     
  2. Avec des librairies comme jQuery et Lodash : http://jsbin.com/posowem/edit?html,js
  3. Avec un framework comme vueJS, ici dans un exemple simple : http://jsbin.com/pigolozuva/1/edit?h...console,output 
  4. Idem mais avec des données distantes obtenues par fetch à partir d'une API REST : http://jsbin.com/dizigehata/1/edit?h...console,output

A propos de REST:

Remarque : on peu faire des requêtes REST avec XhR2fetch API(pour les curieux : quelques mots sur GraphQLet Appolo

On peut aujourd'hui gérer la progression des uploads et downloads avec fetch et l'API des streams (voir https://streams.spec.whatwg.org/demos/)

Suite de l'étude de VueJS

Créer des composants avec VueJS

Reprenez un des derniers exemples faits avec VueJS, ma gestion d'une todo list: http://jsbin.com/pigolozuva/1/edit?h...console,output 

Dans cet exemple, on ne peut pas instancier plusieurs "Vues". Mais on peut associer la VueJS à un "faux" élement custom HTML, comme ici: http://jsbin.com/penadanife/edit?htm...console,output

Exercice à faire: inspirez-vous de cet exemple pour gérer une liste de hobbies, mais avec les contraintes indiquées dans les commentaires HTML de ce squelette d'application: http://jsbin.com/guwetoy/edit?html,js,output

Correction (ne regarder qu'après avoir vraiment essayé, ou vu la correction en live conding) : http://jsbin.com/guwetoy/1/edit

Développer en mode "CLI" avec un environnement de build/testy

Cette fois-ci, pour terminer l'introduction à VueJS, le plus élégant/simple des trois gros frameworks "industriels" modernes (React, VueJS, Angular), nous allons regarder comment on peut développer avec "un environnement de développement", qu'on appelle "CLI" pour "Command Line Environment". 

Les trois frameworks cités, mais aussi Polymer dont on vient de parler, proposent un environnement "CLI".

Travail à faire :

  1. Installer Vue-cli: exécuter "npm install -g vue-cli", si vous êtes sous Linux ou Mac OS, il se peut que vous deviez faire "sudo npm install -g vue-cli" (essayez d'abord sans le sudo).

    Idem, sous windows il se peut que vous deviez avoir ouvert le terminal DOS en mode "administrateur".
     
  2. Créez un répertoire pour le TP
     
  3. Allez dans ce répertoire en mode ligne de commande, depuis votre terminal
     
  4. On va maintenant créer une application VueJS avec le mode "webpack-simple" (cf la page de doc: https://github.com/vuejs/vue-cli), on peut en effet créer plusieurs types de projets avec vue-cli.

    La commande à exécuter est "vue init webpack-simple nom_de_votre_app", je suggère quelques chose comme nom qui ressemble à "my-app-vue-cli1" par exemple. Vous exécuterez donc la commande : "vue init webpack-simple my-app-vue-cli1"

    Vous devrez alors répondre à un petit questionnaire, en général vous faites "enter", répondez "non" si on vous demande d'utiliser "SAAS" (un pré-processeur CSS comme LESS).

    Cela va créer un sous-répertoire my-app-vue-cli qui contiendra tout ce qu'il faut pour démarrer :
    • Une application exemple,
    • un environnement de développement,
    • Des fichiers de configuration pour webpack etc.
       
  5. Allez dans le répertoire de l'application et faites "npm install" pour installer les dépendances (de l'environnement de développement, et du framework)

     
  6. Exécutez l'application de test avec "npm run dev". Si jamais vous avez une page qui affiche "ERR EMPTY RESPONSE", il se peut que vous deviez changer le port du serveur de dev. Allez dans le fichier webpack.config.js et ajoutez une ligne "port:3000" par exemple, dans la config du devserver. 

    Voici ce que j'ai dans ma config:

    devServer: {
        historyApiFallback: true,
        noInfo: true,
        overlay: true,
        port:3000
    },
     
  7. Etudier le code du fichier main.js, index.html et App.vue

  8. Créer un composant User.vue qui affiche le nom d'un utilisateur
    Ici un exemple de code: User.vue

  9. Créer un composant Info.vue qui affiche juste des infos supplémentaires sous forme de <p>, et qui soit LOCAL à User.vue (voir Live Coding)

  10. Ajouter dans App.vue un <p>Ceci est un test<p>. Que fait le CSS de User.vue ? Supprimer l'attribut "scoped" de la balise <style> de User.vue, que se passe-t-il ?
     
  11. En étant sûr d'être dans le répertoire du projet faites "npm install -save vue-router" pour installer le module de routage de vueJS.

  12. Dans main.js ajoutez les lignes relatives au routeur (import, Vue.use, définition des routes, etc.) pour que le fichier ressemble à ceci :
    import Vue from 'vue';
    import VueRouter from 'vue-router';
    import App from './App.vue';
    import User from './components/User.vue';
    import Blog from './components/Blog.vue';
    import Compte from './components/Compte.vue';

    // Définition des routes
    Vue.use(VueRouter);

    const routes = [
        {path:'/blog', component: Blog},
        {path:'/compte', component: Compte},
        {path:'/', component: User},
    ]

    const router = new VueRouter({
        routes: routes,
        mode:'history'
    })
    // La ligne ci-dessous rend le composant User utilisable
    // partout, dans tous les fichiers .vue
    // C'est un GLOBAL COMPONENT
    Vue.component("app-user", User);

    new Vue({
    el: '#app',
    router:router,
    render: h => h(App)
    })
  13. Remplacez le template de App.vue par le code suivant et testez:
<template>
  <div id="app">
    Hello {{msg}}

    <div>
      <router-link to="/">Home</router-link>
      <router-link to="/blog">Blog</router-link>
      <router-link to="/compte">compte</router-link>
    </div>

    <router-view></router-view>

    <app-user></app-user>
      <p>Ceci est un test</p>
  </div>
</template>

Correction de l'exercice: VueJSExoCli.zip, faire "npm install" et "npm run dev" une fois dezippé.

Séance 2: suite VueJS, intro à React

Avoir une vue de l'écosystème JavaScript (sites vus en cours)

Comment faire de belles interfaces Web avec VueJS ?

Element et iView sont les deux kits de composants d'interface utilisateur les plus populaires, tous deux axés sur le développement rapide d'interfaces utilisateur Desktop. Mint UI et vux, d'autre part, sont les deux packages les plus populaires pour faire des interfaces utilisateur pour mobile.

Vuetify est un framework de composants au look and feel "Material Design" qui peut être utilisé à la fois pour les applications web mobiles et de bureau, et est probablement le plus riche en fonctionnalités de rendu côté serveur, support des Progressive Web Apps et templates en mode CLI. Il y a aussi Vue Material qui met davantage l'accent sur le strict respect des spécifications Material Design.

ALLEZ, PASSEZ UN PETIT MOMENT 0 EXPLORER CES PACKAGES DE GUI POUR VueJS !!!

Exercice à faire pour la semaine prochaine : proposer une démo dans un exemple fait par vous, utilisant des composants de un ou plusieurs d'entre eux.

Introduction à React

Exercices d'introduction, dans une IDE en ligne

On peut faire du react dans JsBin/JsFiddle/CodePen, mais croyez-moi, juste pour de petits exemples !

Exercice à faire en vous aidant des exercices précédents:

Pour vous donner une idée du résultat attendu,voici l'équivalent en VueJS: http://jsbin.com/guwetoy/1/edit?html,output

Je conseille de partir de cet exemple React: le composant en classe ES6

En vous aidant de l'exemple fait en classe en live coding, voud devrez faire incrémentalement, en testant après chaque étape :

  1. Créez un <div> et affichez dedans un composant Root avec React (l'App des exemples)
     
  2. Affichez un tableau de hobbies dans ce <div> (foot, tennis, jeux video, etc.) sous la forme d'une liste. Chaque hobby sera un <li>. Vous fournirez des hobbies par défaut.
     
  3. Ajoutez un bouton 'Nouveau Hobby' et un champ input pour saisir le nom du hobbie à rajouter. La liste doit se mettre à jour.
     
  4. Rendez les hobbies clickables pour qu'on puisse les supprimer
     
  5. Un message <p>Hobby supprimé !</p> devra apparaitre lorsqu'un hobby est supprimé
     
  6. Ajoutez un compteur de hobbies (<p>Hobbies: 4</p>) au-dessus de la liste des hobbies, qui indiquera le nombre de hobbies dans la liste.
     
  7. Vous changerez les styles CSS des éléments de la liste pour qu'ils s'affichent en rouge et vert à chaque ligne, en alternance. Vous utiliserez aussi des classes CSS dynamiques pour afficher le compteur en rouge si le nombre de hobbies est supérieur à trois, en vert sinon. 
     
  8. Chaque <li>, chaque hobby, sera maintenant dans un composant <Hobby/> 

ICI UNE CORRECTIONhttps://codepen.io/w3devcampus/pen/b...m?editors=1010

Exercices avec un environnement "CLI"

Si on va voir la page de facebook sur "how to start with React", il y a un chapitre qui concerne le mode "CLI": https://reactjs.org/docs/add-react-to-a-new-app.html

  1. Vous devez avoir nodeJS correctement installé (node, npm, etc, tout ceci doit fonctionner...)
     
  2. Installez l'extension Google Chrome "React Developer Tools" (https://chrome.google.com/webstore/d...jfkapdkoienihi), elle existe aussi pour Firefox.
     
  3. Installez une bonne fenêtre terminal pour Windows -si vous êtes sous windows comme http://cmder.net/ ou autre (github bash, etc.) si je vous vois avec une fenêtre DOS basique vous allez m'entendre !
     
  4. Installer les packages "babel" et "emmet" si vous êtres sous Sublime Text 3 ou Atom. Ca doit etre ok pour Visual Studio Code, WebStorm etc.
     
  5. Ouvrir la ligne de commande et exécuter la commande "npm install -g create-react-app",
    • Pour vérifier que ça fonctionne, créez un autre répertoire nommé "react_cli" et cd dedans,
    • Executez "create-react-app hello-world" (ça prend du temps, quelques minutes)...
    • Allez dans le répertoire créé (cd hello-world), et faites "npm install" (là aussi, quelques minutes)
    • Exécutez le programme en tapant "npm start", ça doit ouvrir automatiquement le browser sur le port 3000 et afficher une page avec le logo React qui tourne.
    • Editez le code du fichier src/App.js, changez le texte et sauvez -> la page Web de l'application doit se rafraichir automatiquement.
       
  6. Maintenant on va étudier le code, regardez les fichiers html, js, les configs etc.
     
  7. Essayez de modifier la partie "render" de App.js... hmmm ok. Bon, on va faire un simple composant <Username name="toto"/> qu'on va mettre dans un sous répertoire "components" dans les sources, il va simplement afficher un nom passé en attribut/props dans un paragraphe en couleur. Vous ajouterez dans <App/> Plusieurs instances de ce composant.

Exercice: refaire dans le projet les hobbies en mode CLI !

Séance 3: Utilisation de FireBase, une base de données basée cloud synchronisée

  1. Voir demo du prof :-)
     
  2. Vous allez le faire vous-même:

ETAPE 1 : Il faut commencer par modifier l'exemple des hobbies pour qu'il fonctionne non pas avec un tableau mais avec un objet. Firebase ne sais synchroniser que des objets, pas des tableaux:

Dans App.js :

   this.state = {
      hobbies : {
        hobby0: 'tennis',
        hobby1: 'golf'
      }
      // ...
    };

 Il faudra modifier plusieurs parties du code en conséquence...

  • addHobbies, removeHobbies...

    Hints: vous pouvez utiliser l'opérateur ES6 ... pour cloner un objet. 
     
  • render (il faudra itérer sur les propriétés d'un objet maintenant, excellent exercice !)

    Hint: Object.keys(this.state.hobbies).map((key, index) => {... }

Ex de code:

addHobby() {
/* OLD VERSION WITH ARRAY
const oldHobbies = this.state.hobbies;
this.setState({
hobbies: oldHobbies.concat(this.state.input),
input : ""
});
*/
 
  // faire une copie de l'objet hobbies
const hobbies = {...this.state.hobbies};
// Ajouter le nouveau hobby
const timestamp = Date.now();
hobbies[`hobby-${timestamp}`] = this.input.value;
 
this.setState({hobbies});
console.log(this.state.hobbies)
}
removeHobby(key) {
/* OLD VERSION WITH ARRAYS
const oldHobbies = this.state.hobbies;
const position = oldHobbies.indexOf(hobby);
this.setState({
hobbies: oldHobbies.filter((el, index) => {
return (index !== position)
}),
hobbyWasDeleted : true
});
*/
  // faire une copie de l'objet hobbies
     const hobbies = {...this.state.hobbies};
 
// Supprime le hobby dont la cle key a ete passee en parametres
//delete hobbies[key]; // ne marche pas avec firebase
hobbies[key] = null;
 
// Mettre a jour l'etat
// En ES6 vous pouvez juste taper {'hobbies'} au lieu de {hobbies:hobbies}
this.setState({hobbies});
}

Et pour render, exemple d'iterateur sur un objet, comparer par rapport au code qui itere sur un tableau, dans les exemples vus precedemment:
 

// iterateur sur les proprietes de l'objet
let list = Object.keys(this.state.hobbies).map((key, index) => {
// key = element courant (propriete courante de l'objet)
consthobby = this.state.hobbies[key];
const liStyle = {
backgroundColor:index % 2 === 0 ? 'lightpink' : 'red'
};
return <li key={key} style={liStyle} onClick={() => this.removeHobby(key)}>{hobby}</li>
});

ETAPE 2 : on va devoir, comme pour les exemples faits avec vueJS, utiliser le "cycle de vie" du composant (https://reactjs.org/docs/react-component.html#the-component-lifecycle), et charger des données distantes depuis FireBase quand le composant est "monté", et aussi fermer la connexion quand il est "démonté". On va pour cela définir les méthodes 

App.js : 

  componentWillMount() {
    console.log("Will mount")
    // this runs right before the <App> is rendered
  }

  componentWillUnmount() {
      console.log("Will unmount")
  }

  Implémentez ces méthodes et vérifiez bien qu'elles sont appelées...

ETAPE 3 : on va créer une base sur FireBase

  • Allez sur https://firebase.google.com/
     
  • Cliquez sur "accèder à la console" ou "Get Started" selon la langue...
     
  • Cliquez sur "+" pour ajouter un projet, appelez-le "React-INTENSE-hobbies" par exemple. Dans les fenêtres de dioaglogue ne cochez que la dernière case dans la première fenêtre, aucune dans la seconde.
     
  • Cliquez à gauche sur "database" et créer une "realtime database".
     
  • Choisissez le mode "test" sans authentification.
     
  • Cliquez sur "ignorer" pour virer le warning.
     
  • Cliquez à gauche sur "Project Overview", et au milieu de la page sur "Ajouter Firebase à votre application Web", une fenêtre s'ouvre avec des bouts de JS. Voir cette image 
  • Gardez cet onglet ouvert

ETAPE 4 : on ajoute au projet le code pour se connecter à la base:

Dans votre projet, au même niveau que index.js, créez un fichier base.js, et mettez ceci dedans (attention a copier/coller les infos depuis le site, pour que cela corresponde à VOTRE BD)

import Rebase from 're-base';

const base = Rebase.createClass({
// copier les 3 premières lignes de VOTRE config de votre base !!!
 // NE PRENEZ PAS LES VALEURS QUI SONT ICI !!!
    apiKey: "AIzaSyCW_WJJb16YVDlsdsd9c0YNNGnfdssorzWGFRU2ScU",
    authDomain: "react-mbds-firebase.firebaseapp.com",
    databaseURL: "https://react-mbds-firebase.firebaseio.com" // pas de , à la fin
});


export default base;


ETAPE 5 : on ajoute le module npm re-base pour "parler à firebase"

On ajoute une ligne au fichier package.json pour installer la lib npm qui va bien:

  "dependencies": {
    "react": "^16.1.1",
    "react-dom": "^16.1.1",
    "react-scripts": "1.0.17",
    "re-base": "2.2.0"// -> ajouter cette ligne, mettez bien 2.2.0 !
  },

 Faites "npm install", ça va installer re-base dans node_modules

ETAPE 6 : on va utiliser re-base pour synchroniser l'état du composant, c'est-à dire les hobbies:

Dans App.js:

....
import base from './base';
....

componentWillMount() {
    //alert("toto")
    // this runs right before the <App> is rendered
    this.ref = base.syncState("hobbies", {
      context: this,
      state: 'hobbies'
    });
  }

  componentWillUnmount() {
    base.removeBinding(this.ref);
  }


Etape 7 : testez !

Sauvez, testez. Ouvrez dans un onglet votre base et regardez les données en sync. Ouvrez deux onglets avec l'appli React, regardez...

Correction

Séance 4 - présentation de NodeJS et premiers exercices simples

Outils à installer

  • Un bon éditeur de code prêt pour le dev front-end: sublime text 3, visual studio code, atom, etc. Pensez à installer les packages emmet, babel, etc.
  • Si vous êtes sous windows, un bon terminal, acceptant le copier/coller, la colorisation, le multi-onglet ou multi-fenêtre, par exemple http://cmder.net/, powershell (de microsoft, déjà installé sous win10), hyperterminal (payant), console2, powercmd, colorconsole, mobaextrem, terminal wings, conemu, 

Casablanca : exemples JsBin sur les objets JavaScript, fait en cours: http://jsbin.com/nemaxonani/edit?js,console

TP - routage avec le module ExpressJS, Web Services RESTFUL

Supports de cours: transparents de présentation de Express 

  • TP:
    1.  Récupérez cette archive, dezippez là quelque part, avec la ligne de commande, faites cd dans le répertoire TP_ROUTAGE_EXPRESS_CRUD_AJAX créé, et exécutez la commande "npm install".

      Ceci devrait créer un sous directory node_modules contenant les modules nécessaires (dans notre cas: express et multer).
       
    2. Suivez les consignes du prof et les explications au tableau.
    3. Les bonnes pratiques pour créer une API RESThttps://blog.octo.com/designer-une-api-rest/

    4. FACULTATIF: Avec Multer on peut aussi uploader des fichiers Testez cet exemple qui fait de l'upload de fichiers. Pensez à installer les modules express et multer dans le répertoire avant d'exécuter.

TP - MongoDB

  • Vous allez, dans cette séance apprendre les bases de l'utilisation de MongoDB depuis une application écrite en JavaScript et exécutée avec NodeJS. Dans un second temps, vous ré-utiliserez le code qui fait le CRUD sur une base d'exemples de MongoDB, en le déplaçant dans des méthodes app.get, app.post etc du TP de la séance 3, pour faire une application utilisable depuis des URLs.

1 - Installer MongoDB sur votre machine

Suivez les installations propres à votre système d'exploitation situées sur cette page du site officiel. Ne choisissez pas l'installation manuelle.

Une fois installé lancez la commande "mongod" en ligne de commande. Si le daemon mongoDB ne se lance pas, regardez les erreurs.

Sur mon Mac j'ai fait:

  • brew update
  • brew install mongodb
  • mkdir -p /data/db
  • chmod 777 /data/db (pour autoriser un user lambda à écrire dedans)
  • mongod (pour exécuter MongoDB)

2 - Créer et peupler une collection par défaut (avec un dataset issu du tutorial MongoDB officiel)

  • Récupérez donc ce fichier : primer-dataset.json. Vous allez devoir récupérer le fichier primer-dataset.json (assez gros, attention, ne pas faire copier/coller), et exécuter la commande suivante, qui créer une bd "test" et ajoute dedans la collection "restaurants" :
    • mongoimport --db test --collection restaurants --drop --file primer-dataset.json
  • Une fois l'importation faite, garder l'onglet ouvert sur cette page, car on va continuer le tutorial à l'étape 5.

3 - Installer un outil d'administration sympa

Je vous recommande fortement MongoChef, un produit commercial mais gratuit pour utilisation non commerciale. Le télécharger sur: https://studio3t.com/

4 - Ouvrir 3T STudio et voir la collection que l'on vient d'importer

  • S'assurer que MongoDB tourne (mongod doit être lancé, ou bien vous devez avoir installé MongoDB en service)
  • Lancer l'application 3T Studio, connectez-vous sur MongoDB. Les valeurs par défaut doivent être Ok, normalement.
  • Ouvrir la collection "restaurants" dans la base "test"

Quelques screenshots:

MongoChef1.jpg

MongoChefRequestBuilder.jpg 

5 - Installer le driver MongoDB pour NodeJS

  • Allez dans le répertoire du TP précédent (routage avec express etc)
     
  • Exécutez npm install -save mongodb
    • Cette dernière commande ne fait qu'installer le driver mongodb pour nodeJS dans le répertoire node_modules.

6 - Tester des requêtes CRUD avec NodeJS et express   

FAIT EN LIVE CODING: inserer + supprimer des lignes d'une table HTML depuis JavaScript: http://jsbin.com/hinilet/edit?console,output

  1. Récupérez cette archive qui est une version modifiée de l'exercice précédent: TPRoutageExpressWithMongo3.zip 
     
  2.  Dezipper, allez dans le répertoire créé (TPRoutageExpressWithMongo3) et faites "npm install"
     
  3. Exécutez node serverCrudWithMongo (ou nodemon)
     
  4. Ouvrez localhost:8080

  5. Etudiez le code, regardez en particulier comment, quand on clique sur le premier bouton GET AJAX un tableau est construit dynamiquement. 
     
  6. Etudiez ce que le prof a fait en live coding: la suppression et la modification d'une donnée.

A FAIRE : essayer d'ajouter un findByName et un count à l'application précédente.

Corrections pour le count et pour le findByName:

Voir la doc de MongoDB pour les requêtes comprenant des expressions régulières: https://docs.mongodb.com/manual/refe...r/query/regex/

Dans serverCrudWithMongo.js:

// ICI c'est autorisé par la norme REST car
// "count" est un mot réservé, on ne risque pas de
// le prendre pour une TABLE ou une collection
// cf la partie "reserved words" de
// https://blog.octo.com/designer-une-api-rest/
app.get('/api/restaurants/count', function(req, res) { 
	// on renvoie le nombre de restaurants
 	mongoDBModule.countRestaurants(function(data) {
 		var objdData = {
 			msg:"Count effectué avec succès",
 			data: data
 		}
 		res.send(JSON.stringify(objdData)); 
 	});     	
});

// On va récupérer des restaurants par un GET (standard REST) 
// cette fonction d'API peut accepter des paramètres
// pagesize = nombre de restaurants par page
// page = no de la page
// Oui, on va faire de la pagination, pour afficher
// par exemple les restaurants 10 par 10
app.get('/api/restaurants', function(req, res) { 
	// Si présent on prend la valeur du param, sinon 1
    let page = parseInt(req.query.page || 0);
    // idem si present on prend la valeur, sinon 10
    let pagesize = parseInt(req.query.pagesize || 10);
    let nom = req.query.nom;

	if(nom) {
    	// find by name
	 	mongoDBModule.findRestaurantsByName(nom, page, pagesize, function(data) {
	 		var objdData = {
	 			msg:"restaurant recherchés par nom avec succès",
	 			data: data
	 		}
	 		res.send(JSON.stringify(objdData)); 
	 	}); 
    } else {
    	// find normal
	 	mongoDBModule.findRestaurants(page, pagesize, function(data) {
	 		var objdData = {
	 			msg:"restaurant recherchés avec succès",
	 			data: data
	 		}
	 		res.send(JSON.stringify(objdData)); 
	 	}); 

    }
});

Dans app_modules/crud-mongo.js:

exports.countRestaurants = function(callback) {
	console.log("DANS COUNT")
	MongoClient.connect(url, function(err, client) {
                var db = client.db(dbName);
		db.collection('restaurants')
		.count(function(err, res) {
			console.log("COUNT = " + res)
			callback(res);
		});
	});
};

exports.findRestaurantsByName = function(nom,page, pagesize, callback) {
    MongoClient.connect(url, function(err, client) {
            var db = client.db(dbName);
    	    console.log("pagesize = " + pagesize);
    	    console.log("page = " + page);
    console.log("FIND BY NAME nom=" + nom);

    	// syntaxe recommandée
    	// Cf doc mongodb: https://docs.mongodb.com/manual/reference/operator/query/regex/
    	// The $regex value needs to be either the string 
    	// pattern to match or a regular expression object. 
    	// When passing a string pattern, you don't include 
    	// the / delimitters
    	// VERSION avec $regexp et $options
    	let myquery = {
    		"name": {
    			$regex: ".*" + nom + ".*", 
    			$options:"i"
    		}
    	}

    	// VERSION avec objet RegExp
    	//let myquery =  {'name' : new RegExp('^.*'+nom+'.*$',"i")};
    	// ou, si on veut être "case sensitive"  
    	//let myquery =  {'name' : new RegExp('^.*'+nom+'.*$')};
        if(!err){
            db.collection('restaurants')
            .find(myquery)
            .skip(page*pagesize)
            .limit(pagesize)
            .toArray()
            .then(arr => callback(arr));
        }
        else{
            callback(-1);
        }
    });
};

Suite de l'étude de Réact : liaison avec Node/MongoDB

Ressources externes :

  • Acheter pour zéro euro le livre : https://leanpub.com/the-road-to-learn-react-french

    • Le livre existe aussi en anglais, gratuit, avec une version un peu plus à jour, sur le même site et franchement, la traduction française est pas géniale... je recommande plutôt cette version si vous n'êtes pas trop mauvais en anglais.
       
    • Récupérer les sources dans le github du livre (lire les premières pages, le github est indiqué).
       
  • MOOC : React for beginners

    • Voir le prof...
       
    • Le cours sur Redux par le même auteur est 100% gratuit, sur son site web

Travailler avec les restaurants et la base MongoDB

  • Objectif : refaire quelque chose de ce genre (ici en VueJS), mais avec React :

    1. Récupérez cette archive 
    2. Dezippez-là
    3. Allez dans le répertoire et faites "npm install"
    4. Assurez-vous que MongoDB tourne (lancer mongod dans une fenêtre si ce n'est pas le cas)
    5. Exécutez "node serverCrudWithMongo.js"
    6. Ouvrez localhost:8080/tableVue.html
    7. Testez les fonctionnalités
    8. Regardez le code de tableVue.html pour une application VueJS assez "classique" réalisée sans utiliser le mode CLI de VueJS.
 

Si vous voulez ajouter le support "cross domain" à votre projet node/MongoDB

Ajouter les lignes suivantes dans la configuration de votre serveur (fichier serverCrudWithMongo.js), ça se passe dans la configuration de express, c'est l'équivalent des "Servlet Filters" en JavaEE :

app.use(function (req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE »);

    next();
});

Travail à faire (à rendre et noté) : refaire l'application VueJS qui fait le CRUD sur les restaurants, mais en React

Vous commencerez pas simplement afficher des restaurants dans une table. Peu importe si ce n'est pas joli... On utilisera un tableau de restaurants dans le "state" de React en s'inspirant des exemples vus précédemment avec les hobbies. On utilisera la méthode componentDidMount() pour faire un fetch sur les restaurants:

componentDidMount() {
    console.log("Composant avant premier affichage")
    // ici aller chercher des données dans une source de données (ex: GET /api/restaurants
  }

Si vous avez récupéré le livre recommandé au début de cette section, il y a un chapitre qui s'intitule "Aller chercher les données" qui montre des exemples d'utilisation de fetch en React.

Premiers pas avec Angular (4/5)

1 : création d'une application "squelette"

  1. Installer angular-cli : dans une fenêtre de terminal, tapez la commande "npm install -g @angular/cli" (éventuellement avec "sudo" avant si vous êtes sous Linux ou Mac OS)

  2. Créez un répertoire "exo1Angular" et faites cd dans ce répertoire,
  3. Générez une application "squelette" angular en tapant la commande "ng new angular-framework-intro"
  4. Faites cd angular-framework-intro et ouvrez visual studio code sur ce répertoire (commande "code ." sur Mac)
  5. Faites npm install pour installer les modules nécessaires (pour l'application et pour l'environnement de développement)
  6. Exécutez le projet en lançant la commande ng serve --open dans le répertoire
  7. Ok, maintenant faites "view source" sur la page, que remarquez-vous ? Comparez avec React et VueJS... Qu'en déduisez-vous ? A propos, est-ce qu'on a installé une extension dans le browser ?
  8. Etudions maintenant la structure du projet....

2 : affichage d'une liste d'éléments

  1. Regardez le fichier index.html, remarquez l'élément <app-root></app-root>, est-ce du HTML standard ?
  2. Regardez les fichiers src/app.component.tssrc/app.component.html et src/app.component.css
  3. Modifiez le fichier de templates app.components.html et faites ctrl-s,
  4. Regardez le fichier app.module.ts, Angular va vous obliger à mettre à jour ce fichier très régulièrement.
  5. Maintenant on va effacer le contenu du fichier de template, et on va essayer d'afficher une liste d'éléments : CA SE PASSE EN LIVE CODING (une correction sera postée ici à la fin), utilisation de *ngFor (<li *ngFor="let el of elements">...</li> si elements est la propriété du composant -un tableau de chaines de caractères-), un peu l'équivalent du v-for de VueJS.
  6. Ajout d'un bouton pour ajouter un nouvel élément, utilisation de (click)="expression" comme attribut,
  7. Regardons comment afficher une ligne verte, une ligne rouge, etc. Utilisation de [ngStyle]="{propriété CSS : expression}", écrire une fonction getColor(element) comme dans les exemples qu'on avait fait avec VueJS et React, et l'appeler dans l'expression).

: création d'un nouveau composant

  • On va créer "manuellement" un nouveau composant intitulé "username", qui sera juste un<li> qui affichera la valeur de la propriété username. Pour cela, créer le fichier "app/username.component.ts, et il doit ressembler à cela.
    REMARQUE: vous pouvez utiliser la ligne de commande pour ajouter un nouveau composant: 

    > ng generate component username

import { Component, Input } from "@angular/core";

@Component ({
    selector: 'app-username',
    template:`
    <p>{{username}}</p>
    `
})

export class UsernameComponent {
    @Input() username :string;
}

Remarquez qu'on n'a pas utilisé ici de template html séparé, à la place on a mis le template directement sous forme de chaine de caractère entre les caractères `....`

Le @Input sert à définir une propriété qu'on pourra passer via des attributs HTML, c'est l'équivalent des "props" de VueJS et de React.

Maintenant, ajoutez des instances de ce composant dans le template app.components.html:

<app-username [username]="'Michel'"></app-username>

<app-username [username]="'John'"></app-username>

Regardez ce que cela donne.... rien, ouvrez la console de debug...

C'est normal, il faut déclarer le composant dans le fichier app.module.ts (c'est pénible... mais vous verrez qu'on peut automatiser cela en créant les composants avec la ligne de commande)... Ajoutez le composant dans app.module.ts et cela devrait fonctionner.

Maintenant on veut pouvoir cliquer sur un nom et afficher un message dans le template du composant principal. On va faire comme en VueJS : envoyer un événement quand on clique sur le nom.

4 : définition d'un événement qui sera envoyé du composant "fils" vers le composant "père"

  1. Dans le composant (app/username/username.component.ts), définir un événement comme ceci: 
export class UsernameComponent {
    @Input() username :string;
    @Output() userClicked = new EventEmitter<string>(); // définition d'un événement

    onUsernameClicked() {
        this.userClicked.emit(this.username);            // émission de l'événément
    }
}

Et dans le template (app/username/username.component.ts) :

    template:`
       <p (click)="onUsernameClicked()">{{username}}</p>
    `

Ainsi, dans le template du composant (app.component.html) qui instancie ce composant, on pourra écouter l'événement "userClicked" :

<app-username [username]="'Michel1'" (userClicked)="onUserWasClicked($event)"></app-username>
<app-username [username]="'John'"    (userClicked)="onUserWasClicked($event)"></app-username>

Et maintenant on peut écrire la méthode onUserWasClicked(username) dans app.component.ts :

onUserWasClicked(username: string) {
    alert(username);
}

Testez l'application : en cliquant sur un nom, ça doit afficher une alerte avec la valeur associée.

5 : binding bi-directionnel avec [(ngModel)]="nom"

  • Définissez un champs de saisie dans le template pour une propriété "nom" que vous ajouterez dans le fichier .ts de app.component.ts
  • Dans le template, affichez la valeur de cette propriété en-dessous du champs de saisie. 
  • Tapez quelque chose dans le champ de saisie
  • Plus simple qu'en React non ? Ca ressemble au v-model de VueJS non ?

ICI UNE CORRECTION DES ETAPES PRECEDENTES (exemple fait en live). Dezippez, cd dans le repertoire, npm install puis ng serve --open

6 : refaire l'exemple des hobbies complet, mais en angular

 En vous aidant de l'exemple précédent : 

  1. Dans le composant app.component (.ts/html/), définissez un tableau de hobbies et affichez-les dans une liste (fournissez quelques hobbies par défaut)
     
  2. Ajoutez un bouton 'Nouveau Hobby'  + un champ <input>. Quand on clique le bouton on ajoutera le hobby et la vue se mettra à jour
     
  3. Rendez chaque hobby clickable. Si on clique un hobby on le supprime 
     
  4. Faites apparaitre un message <p>Hobby supprimé! dans un </p> qui ne sera visible que lorsque au moins un hobby a été supprimé (soyez créatifs! Il y a plusieurs manières de faire)
     
  5. Ajouter un compteur de hobbies (<p>Nombre de Hobbies: ...</p>) au-dessus de la liste des hobbies
     
  6. Changez le style CSS du compteur, selon sa valeur: vert si moins de 3 hobbies, rouge sinon
     
  7. Transformez les éléments <li> en un composant réutilisable <app-hobby>
     
  8. On veut remplir les hobbies au démarrage de l'application en récupérant les hobbies au format JSON sur l'URL : https://my-json-server.typicode.com/...ffa/hobbies/db (au passage, j'ai utilisé les services de jsonplaceholder.typicode.com pour servir un fichier json qui se trouve sur un de mes repository github). LIVE CODING AVEC LE PROF pour voir comment créer un service
    • Commande pour créer un service : "ng generate service hobby" (va créer le fichier hobby.service.ts et le fichier pour les tests)
    • Correction de cet exercice
       
  9. Exercice à faire : afficher les restaurants de votre base MongoDB (juste les noms pour commencer) à la place des hobbies...
    • Pour autoriser le cross origin, ajouter ces lignes dans le fichier serverCrodWithMongo.js d'un des TPs précédents, après les autres lignes de la configuration express qui font des app.use...
    • // Pour autoriser le cross origin
      app.use(function (req, res, next) {
          res.header("Access-Control-Allow-Origin", "*");
          res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
          res.header("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE");
          next();
      });

Démarrage du mini projet

Sujet proposé (mais j'accepte sujets persos)

Contraintes : 

  • A faire à deux
  • Utiliser un des frameworks vus en cours
  • Back end Node/Mongo ou FireBase

Hébergement sur HEROKU.COM

Exemples d'applications prêtes à déployer sur Heroku (regardez les README.txt pour les explications)