IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

NodeJS Discussion :

Afficher la météo avec node et openweathermap


Sujet :

NodeJS

  1. #1
    Membre habitué Avatar de lostsoul
    Homme Profil pro
    Rédacteur web, blogueur, développeur web junior
    Inscrit en
    Novembre 2003
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Rédacteur web, blogueur, développeur web junior
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2003
    Messages : 759
    Points : 184
    Points
    184
    Par défaut Afficher la météo avec node et openweathermap
    Bonjour,

    Je voudrais, avec node, afficher la météo sur une page ejs, depuis openweathermap. Dois-je utiliser un npm ou directement un code comme celui-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    var querystring = require('querystring');
    var request     = require("request");
    var result = '';
    var text = '';
     
    var openWeatherMapQuery = querystring.stringify({
      q: "Bourges, France",
      lang: "fr",
      units: "metric"
    });
    var openWeatherMapURL = "http://api.openweathermap.org/data/2.5/weather?"+ openWeatherMapQuery;
     
    request({
      url: openWeatherMapURL,
      json: true // Nous recevrons un JSON
    }, function (error, response, resp) {
     
      if (!error && response.statusCode === 200) {
     
        var text = "Bulletin météo : "
        text += resp.weather[0].description
        text += ". Il fait actuellement "+ Math.round(resp.main.temp) +" degrés."
     
        var result = querystring.stringify({
          tl: "fr",
          q:  text,
          ie: "UTF-8"
        });
     
        console.log("Météo construite :");
        console.log(text);
        console.log(resp.main.temp);
     
      } else {
     
        console.log("Une erreur est survenue.");
      }
    })
     
    module.exports.result = result;
    module.exports.text = text;
    Je précise que je n'arrive pas à afficher le résultat dans ma page ejs. Est-ce qu'un npm serait mieux ? J'ai vu des examples avec le code directement dans la page web.

    Merci d'avance,
    Très cordialement,

    ANDRE Ani
    ANDRE Ani
    GNU/Linux et Informatique Libre
    https://andre-ani.fr

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    154
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2009
    Messages : 154
    Points : 233
    Points
    233
    Par défaut
    Bonjour lostsoul,

    plusieurs problèmes dans ton scripts:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    module.exports.result = result;
    module.exports.text = text;
    module.exports ne peut être appeler qu'une seul fois, et ne sert pas à renvoyer un résultat de fonction, mais à exporter la fonction elle même pour que tu puisse l'appeler dans d'autres fichiers via un require.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
     
    // toto.js
    function toto (callback) {
       return callback(null, 'j\'ai une blague');
    }
     
    module.exports = toto;
     
    // tata.js
    var toto = require('./toto.js');
     
    toto(function(err, res) {
       if (err) throw err;
       console.log(res);
    });
    je t'invite d'ailleurs à chercher un peu sur la différence entre module.exports et exports.foo, sujet traité mille fois sur le net (et la flemme de tout réécrire )

    autre problème conceptuel, tu essaye de renvoyer le resultat d'un callback en dehors de celui ci. je pense à 'result' et 'text' dans request. Tes resultats, tu doit en faire quelque chose dans :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    function (error, response, resp) { /* ici, car en dehors ils n'existent pas */ }
    soit simplement l'afficher dans la console comme tu le fais, soit renvoyer ces valeurs via un callback

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    
    function openWeatherMap (callback) {
      var querystring = require('querystring');
      var request     = require("request");
      var result = '';
      var text = '';
     
      var openWeatherMapQuery = querystring.stringify({
        q: "Bourges, France",
        lang: "fr",
        units: "metric"
      });
      var openWeatherMapURL = "http://api.openweathermap.org/data/2.5/weather?"+ openWeatherMapQuery;
     
      request({
        url: openWeatherMapURL,
        json: true // Nous recevrons un JSON
      }, function (error, response, resp) {
    
       if (error) return callback(err);
    
     
        if (!error && response.statusCode === 200) {
     
          var text = "Bulletin météo : "
          text += resp.weather[0].description
          text += ". Il fait actuellement "+ Math.round(resp.main.temp) +" degrés."
     
          var result = querystring.stringify({
           tl: "fr",
            q:  text,
            ie: "UTF-8"
          });
     
          console.log("Météo construite :");
          console.log(text);
          console.log(resp.main.temp);
          callback(null, text, resp.main.temp);
     
        } else {
     
          console.log("Une erreur est survenue.");
          callback(new Error("Une erreur est survenue."));
        }
      })
    });
     
    module.exports = openWeatherMap;
    voila en trés gros...

    Est-ce qu'un npm serait mieux ?
    lapin compris!

    Clairement, tu débute avec node.js, c'est pourquoi je t'invite à ne pas te décourager et à revoir la notion de callback et d'asynchronicité.

  3. #3
    Membre habitué Avatar de lostsoul
    Homme Profil pro
    Rédacteur web, blogueur, développeur web junior
    Inscrit en
    Novembre 2003
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Rédacteur web, blogueur, développeur web junior
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2003
    Messages : 759
    Points : 184
    Points
    184
    Par défaut
    Merci beaucoup pour ces explications. Je débute, et c'est un peu la galère j'avoue...
    Bon, j'ai compris pour module.exports et require, ça devrait aller mieux de ce côté là ;-)

    Par contre, ok, la fonction callback est une fonction passée en paramètre d'une autre, mais... Je suis un peu perdu pour comprendre comment récupérer mes variables depuis le callback pour les afficher...

    En plus, je ne suis pas sûr de la variable dont j'ai besoin pour afficher les infos météo, c'est result il me semble.

    /models/meteo.js :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
    function openWeatherMap (callback) {
     
    var querystring = require('querystring');
    var request     = require("request");
    var result = '';
    var text = '';
     
    var openWeatherMapQuery = querystring.stringify({
      q: "Bourges, France",
      lang: "fr",
      units: "metric"
    });
    var openWeatherMapURL = "http://api.openweathermap.org/data/2.5/weather?"+ openWeatherMapQuery;
     
    request({
      url: openWeatherMapURL,
      json: true
    }, function (error, response, resp) {
     
      if (!error && response.statusCode === 200) {
     
        var text = "Bulletin météo : "
        text += resp.weather[0].description
        text += ". Il fait actuellement "+ Math.round(resp.main.temp) +" degrés."
     
        var result = querystring.stringify({
          tl: "fr",
          q:  text,
          ie: "UTF-8"
        });
     
        console.log("Météo construite :");
        console.log(text);
        console.log(resp.main.temp);
        callback(null, text, resp.main.temp);
     
      } else {
     
        console.log("Une erreur est survenue.");
        callback(new Error("Une erreur est survenue."));
      }
    })
    };
     
    module.exports = openWeatherMap;
    /controllers/index.js :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
     
    var result = require('./../models/meteo.js');
    var text = require('./../models/meteo.js');
    var openWeatherMap = require('./../models/meteo.js');
     
    module.exports.index = function (req, res, next) {
      res.send('Hello World');
    };
     
    module.exports.test = function (req, res, next) {
        res.render('test.ejs', {title: 'Page de test'});
    };
     
    module.exports.essai = function (req, res, next) {
        res.render('essai.ejs', {
            title: 'c est un essai',
    	openWeatherMap: openWeatherMap,
    	text: text,
    	result: result
            }
        );
    };
    Enfin, merci encore, je vais continuer à patauger dans tout ça ;-)
    ANDRE Ani
    GNU/Linux et Informatique Libre
    https://andre-ani.fr

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    154
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2009
    Messages : 154
    Points : 233
    Points
    233
    Par défaut
    Attention, ne reprends pas tel quel la fonction openWeatherMap, je devais déposer mon fils à l'école et j'ai répondu très vite, mais il ne faut pas la laisser en l'état.

    et dans ton index.js "module.exports.index = " c'est le mal!

    De plus je viens de voir ton autre fil concernant "Americano] Avoir des pages jade ou ejs", qui commence à tout mélanger, tu devrais en cloturer un des deux.

  5. #5
    Membre habitué Avatar de lostsoul
    Homme Profil pro
    Rédacteur web, blogueur, développeur web junior
    Inscrit en
    Novembre 2003
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Rédacteur web, blogueur, développeur web junior
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2003
    Messages : 759
    Points : 184
    Points
    184
    Par défaut
    Vu l'autre msg.
    Moi, j'ai testé en vitesse parce que j'avais du ménage à faire...

    Je peux supprimer l'autre fil, et on garde celui-la ?
    ANDRE Ani
    GNU/Linux et Informatique Libre
    https://andre-ani.fr

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    154
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2009
    Messages : 154
    Points : 233
    Points
    233
    Par défaut
    va pour celui la!

    Je découvre, et, pour le moment, je voudrais arriver à faire une ptite appli single page
    la base de la base

    Site web ->
    La page est construite dynamiquement coté serveur, qui renvoi le résultat sous forme de HTML au navigateur pour chaque url et à chaque chargement de page.
    sans rechargement de page, le client n'est pas informé des modifications éventuelles sur le serveur.

    Appli web/Single page ->
    Au premier chargement, le navigateur récupère la page HTML principale statique (d'où le single page), et un ensemble de fichiers js qui se charge de construire dynamiquement le contenu coté client. Puis en cas de modification coté client, ce dernier peut interagir avec le serveur via de simple appel ajax.
    Pour gérer la partie client, c'est le boulot de framework tel que backbonejs, angularjs, emberjs, etc... l'api coté serveur est géré avec ce que tu veux: nodejs, php, java, ruby, est les (multiples) frameworks qui vont avec.

    Donc que veux tu faire, un site ou une appli?

    (...)assez simple (authentification locale, puis 2 / 3 trucs à afficher et ou / configurer, peut-être avec une BDD).
    Quand tu dis "assez simple", sache qu'il y a déjà pas mal de concept derrière l'authentification et la bdd

    Il faudrait déjà que tu me dise s'il s'agit juste d'un projet de "test" ou s'il y a une vrai finalité?

  7. #7
    Membre habitué Avatar de lostsoul
    Homme Profil pro
    Rédacteur web, blogueur, développeur web junior
    Inscrit en
    Novembre 2003
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Rédacteur web, blogueur, développeur web junior
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2003
    Messages : 759
    Points : 184
    Points
    184
    Par défaut
    Je connais les bases, le fonctionnement d'un site web (et sa création). J'ai déjà créé des sites avec HTML, CSS, les bases du PHP.

    Je voudrais essayer de faire une appli, pour me former et savoir utiliser Node (au moins les bases).

    Le but la, c'est de me former et d'apprendre les bases, pas de réelle finalité derrière (sauf si vraiment je me débrouille trop bien lol ).
    Bon, on peut peut-être enlever l'authentification, et juste faire quelques petites choses plus basiques (récupérer des infos, les afficher) comme avec la météo, voir essayer d'intéragir avec l'utilisateur peut-être, même si je ne sais pas encore trop comment.
    J'ai un début d'appli qui affiche un flux RSS, voir pour que l'utilisateur choisisse le flux à afficher ?

    Enfin voilà quelques idées, sa part un peu dans tous les sens...
    ANDRE Ani
    GNU/Linux et Informatique Libre
    https://andre-ani.fr

  8. #8
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    154
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2009
    Messages : 154
    Points : 233
    Points
    233
    Par défaut
    Je voudrais essayer de faire une appli, pour me former et savoir utiliser Node
    commençons plutôt par un site alors, car Node permettant d’exécuter du code js coté serveur, tu n'as pas besoin de te compliquer les choses avec une application web.

    Donc, pour rappel, Node est composé d'un moteur (interpréteur) JavaScript, et d'un ensemble de libraire permettant d'interagir avec le système hôte (comme lire sur disque dur). En bref, c'est un interpreteur javascript coté serveur. De plus, ces librairie contiennent un serveur http basique. Si tu as déjà fait du php, tu as donc utilisé un interpréteur php (php-fpm ou le module php de apache), et un serveur http comme apache ou nginx.

    Node à la particularité de n'utiliser qu'un seul thread, contrairement à apache qui va créer un thread pour chaque requêtes.(Je pars du principe que tu sais ce qu'est un thread, sinon n’hésite pas à demander)

    Pour gérer de multiples requêtes sans être bloqué par son unique thread, Node stocke chacune de ces requêtes dans une boucle évènementielle, et fais le traitement en arrière plan. Un exemple s'impose:

    1. au temps 0, la requête A entre dans la boucle, son temps de traitement est de 50ms.
    2. au temps 1, premier tour de boucle, A est toujours en attente de réponse.
    3. au temps 2, la requête B entre dans la boucle, son temps de traitement est de 20ms, c'est aussi le deuxieme tour de boucle, et A est toujours en attente
    4. au temps 3, troisième tour de boucle, A et B sont en attente de réponse
    5. le temps passe les tours de boucle aussi...
    6. au temps 10, la requête C entre bla bla, tu as compris le concept
    7. le temps passe les tours de boucle aussi...
    8. au temps 22, la réponse arrive enfin pour B qui va renvoyer sa réponse et sortir de la boucle, A et C sont toujours en attente
    9. au temps 50, la réponse de A arrive, est renvoyé au demandeur, et A sort de la boucle
    10. ...


    Chacune de ces requêtes ce doivent d'être asynchrones, sinon la fonction D synchrone va réclamer son traitement immédiat avant toutes les autres, et pour peu quelle soit un peu longue, disons 100ms, elle va empêcher toutes nouvelles requêtes de rentrer dans la boucle pendant... 100ms

    La force de Node repose donc sur sa capacité à conserver une haute-disponibilité malgré un nombre élevé de requêtes et sans être bloqué par le traitement de requête un peu longue comme un accès au disque dur, enfin une emprunte mémoire constante puisqu'il n'a qu'un seul thread.

    L’asynchronicité:

    la forme la plus emblématique d'asynchronicité est la function callback. Il s'agit d'une fonction qui retourne une autre fonction!

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // la function callback
    function increment(value, callback) {  
       if (typeof value === 'number') value = value + 1;
       return callback(value);
    }
     
    // utilisation de la function callback
     
    var i = 5;
     
    increment(i, function(j) {
       console.log(j);  // @1 -  j affiche 6
    });
     
    console.log(j); // @2 -   j affiche undefined
    et à l'affichage tu obtiens:

    undefined
    6
    dans le déroulé, increment() entre dans la boucle évènementielle, en attente de son traitement, le deuxième console.log(j) est traité immédiatement mais renvoi undefined, puisque j n'est défini qu'à l'intérieur de la function callback; puis le résultat de increment() revient et le premier console.log affiche 6, puisqu'il ce trouve, lui, à l'intérieur du callback.

    J’arrête là pour un premier jet. Dis moi si tout est bien clair avant de passer à la suite avec le module http de Node et l'apport du framework ExpressJS

  9. #9
    Membre habitué Avatar de lostsoul
    Homme Profil pro
    Rédacteur web, blogueur, développeur web junior
    Inscrit en
    Novembre 2003
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Rédacteur web, blogueur, développeur web junior
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2003
    Messages : 759
    Points : 184
    Points
    184
    Par défaut
    Ok, merci pour tout ça. Oui, c'est plutôt clair, ça va pour le moment.

    Que proposes-tu de faire alors comme site ?
    ANDRE Ani
    GNU/Linux et Informatique Libre
    https://andre-ani.fr

  10. #10
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    154
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2009
    Messages : 154
    Points : 233
    Points
    233
    Par défaut
    Que proposes-tu de faire alors comme site ?
    je te propose de rester dans un premier temps sur ce que tu voulais faire initialement. D'abord un site simple, avec une page qui affiche la météo, puis pourquoi pas un site qui affiche un flux rss et la possibilité pour l'utilisateur de choisir son flux en utilisant la bdd redis, puis on peut terminer par le traditionnel moteur de blog en utilisant la bdd mongodb?

    Le module https://nodejs.org/api/http.html

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     // server.js
    var http = require('http');
    var fs = require('fs');
    var index = fs.readFileSync('index.html'); // 3
     
    http.createServer(function (req, res) { // 1
      res.writeHead(200, {'Content-Type': 'text/plain'}); // 3
      res.end(index); // 5
    }).listen(3000); // 2
    1. On creer une instance de serveur http, qui renvoi deux objet dans un callback:

    req pour request, soit un objet comportant les informations du client, comme sont ip et le user-agent.
    res pour response, soit un objet de réponse vide, que l'on va remplir avant de le renvoyer au client.

    2. On fait écouter notre instance de serveur sur le port 3000.

    3. On écrit dans le header de l'objet réponse, que la requête à été correctement traité (code http 200), et on précise le type de la donnée qu'on lui transmet en retour, soit du texte (text/plain) puis qu'il s'agit d'un fichier html.

    3. On lit sur disque dur le fichier index.html, qui se trouve en l’occurrence dans le même répertoire que notre fichier server.js, et l'on stocke le résultat dans la variable index.

    4. On renvoi l'objet res au client, en lui ajoutant pour contenu, celui de la variable index qui contient notre texte contenant des balises HTML, charge au client de l’interpréter à l'aide des informations précisées dans le header.

    Une remarque avant de continuer, sur la fonction fs.readFileSync. Tu remarqueras qu'elle est synchrone (pas de callback) d'où le "Sync". Oui cette fonction est bloquante, mais elle n'est exécuté qu'au démarrage du script et avant que le serveur http soit en attente de requêtes, l'impact est donc négligeable et même bien pratique pour éviter cette forme:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // server.js version "callback hell"
    var http = require('http');
    var fs = require('fs');
     
    fs.readFile('index.html', function(err, index) {  // lecture du fichier index.html de façon asynchone
       if (err) throw err;
       http.createServer(function (req, res) { 
        res.writeHead(200, {'Content-Type': 'text/plain'}); 
        res.end(index); 
      }).listen(3000);
    })
    Mais si utiliser une fonction synchrone avant de démarrer le serveur http n'est pas un soucis, il est capitale de ne plus en utiliser à l'intérieur du serveur lui-même!

    Revenons à notre module http, tu remarqueras que c'est très «bas-niveau», comment gérer plusieurs pages, du routage, la gestion de session, cookies, etc... sans que cela devienne un enfer?

    Donc au commencement il y avait le module http, puis sont apparu les middlewares "Connect" https://github.com/senchalabs/connect#readme

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
     // pompage honteux du readme de Connect
    var connect = require('connect')
    var http = require('http')
     
    var app = connect()
     
    // gzip/deflate outgoing responses
    var compression = require('compression')
    app.use(compression())
     
    // store session state in browser cookie
    var cookieSession = require('cookie-session')
    app.use(cookieSession({
        keys: ['secret1', 'secret2']
    }))
     
    // parse urlencoded request bodies into req.body
    var bodyParser = require('body-parser')
    app.use(bodyParser.urlencoded())
     
    // respond to all requests
    app.use(function(req, res){
      res.end('Hello from Connect!\n');
    })
     
    //create node.js http server and listen on port
    http.createServer(app).listen(3000)
    On crée donc une instance de connect, auquel on greffe des plugins qui agissent comme des middlewares grâce à sa méthode use(); puis on retrouve notre instance de http auquel on donne en paramètre l'instance de connect app, puis on écoute sur le port 3000.

    C'est déjà plus propre, plus modulaire, et toute la magie ce trouve dans le fait que chaque requête de client, traverse chacun des plugins qui modifie l'objet réponse avant de le renvoyer au client.

    Connect est donc une surcouche au module http, et par la suite nous allons voir que ExpressJS est une surcouche de Connect!

    La suite au prochain numéro, n'hésite pas si tu as des questions, car c'est le but du jeu.

    et ne t'inquiete pas, on arrive bientôt à la mise en pratique

  11. #11
    Membre habitué Avatar de lostsoul
    Homme Profil pro
    Rédacteur web, blogueur, développeur web junior
    Inscrit en
    Novembre 2003
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Rédacteur web, blogueur, développeur web junior
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2003
    Messages : 759
    Points : 184
    Points
    184
    Par défaut
    Ok, très bien tout ça ;-)

    Pas de questions pour le moment, c'est clair.

    J'ai déjà vu un peu les bases pour Express, avec les controller, models et views, et les routes vers les différentes pages.

    Ca promet d'être intéressant tout ça, c'est cool ;-)
    ANDRE Ani
    GNU/Linux et Informatique Libre
    https://andre-ani.fr

  12. #12
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    154
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2009
    Messages : 154
    Points : 233
    Points
    233
    Par défaut
    J'ai enfin un peu de temps pour la suite!

    Donc, Express.js est une surcouche de Connect.js, lui même une surcouche du module Http de node.js.

    Express va ajouter principalement deux choses, un routeur top moumoute, et un gestionnaire de moteur de templates avec Consolidate.js.


    • Le routeur


    Si l'on peux donner en premier paramètre une route à la fonction .use() de connect, cela reste très basique.

    Express apporte les expressions régulières pour la définition des routes, ainsi qu'un système permettant de "monter" les routeurs (comme un système de fichier) afin de créer des sub-app.
    Quelques helpers, comme les fonctions .get, .post, .put, .delete, permettant de préciser à quel type de requête la route doit correspondre.

    Plutôt que de tout détailler, je te renvoi à la doc de Express qui me semble assez claire http://expressjs.com/guide/routing.html, quitte à revenir sur certains points.


    • Le gestionnaire de moteur de templates


    Consolidate.js est une lib permettant d'uniformiser la prise en charge d'une tripoté ( actuellement 32) de moteur de templates, de jade à ejs, en passant par mustache,react...

    Il faut simplement le déclarer avec la fonction .set() que l'on verra plus bas, puis simplement rendre la vue avec .render();

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    app.set('view engine', 'jade');
    ...
    app.get('/', function (req, res) {
      res.render('index', { titre: 'Bonjour, le monde'});
    });

    • Tout un tas de helpers


    res.json, res.jsonp, res.links, res.sendFile... permettant des conversions auto

    app.set (app.enable, app.disable), qui permet de modifier les paramètres de la pile. http://expressjs.com/4x/api.html#app.settings.table

    .
    Pour rappel, quand je parle de pile, il s'agit de la pile constituée de tous les middlewares (plugins, routeur et l'éventuel moteur de rendu) que traversera chacune des requêtes.

    La mise en pratique, ce soir, ou demain, bref dés que je peux

  13. #13
    Membre habitué Avatar de lostsoul
    Homme Profil pro
    Rédacteur web, blogueur, développeur web junior
    Inscrit en
    Novembre 2003
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Rédacteur web, blogueur, développeur web junior
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2003
    Messages : 759
    Points : 184
    Points
    184
    Par défaut
    Merci beaucoup, c'est très clair tout çà.
    ANDRE Ani
    GNU/Linux et Informatique Libre
    https://andre-ani.fr

  14. #14
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    154
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2009
    Messages : 154
    Points : 233
    Points
    233
    Par défaut
    ok, alors commençons par la météo (bien qu'en pratique, un petit script vanilla coté client suffit largement pour ce genre de chose...)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    // app.js
     
    var express = require('express');                                        
    var http = require('http');                                                    
     
    var app = express();
     
    app.get('/', function(req, res) {
     
        var openWeatherMapURL = 'http://api.openweathermap.org/data/2.5/weather?q=Bourges,France&lang=fr&units=metric';
     
        require('request').get(openWeatherMapURL, function(err, response, body) {
            if (err) throw err;
     
            if (!err && response.statusCode == 200) {
                res.send(body);
            }
     
        });
     
    });
     
    http
      .createServer(app)
      .listen(3000, function() {
          console.log('Le serveur écoute sur le port 3000');
      });

    1. on crée une instance de express
    2. on défini notre route, le serveur ne répondra que sur un get à la racine. GET /
    3. on crée notre instance de serveur auquel on passe notre instance de express
    4. on écoute sur le port 3000
    5. on affiche un message pour indiquer que le serveur est à l'écoute


    La récupération elle même est trivial; on utilise la fonction request pour faire un get sur une url correspondant à l'api de openWeatherMap, qui nous donne un objet json, contenant toutes les infos sur la localité demandé, et on renvoi cette objet à celui qui nous à fait la demande via un res.send()

    le client obtient ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    jules@lisa ~ $ curl http://127.0.0.1:3000
    {"coord":{"lon":2.4,"lat":47.08},"sys":{"message":0.0048,"country":"FR","sunrise":1428815246,"sunset":1428863689},"weather":[{"id":800,"main":"Clear","description":"ensoleillé","icon":"01d"}],"base":"cmc stations","main":{"temp":15.699,"temp_min":15.699,"temp_max":15.699,"pressure":1021.09,"sea_level":1043.12,"grnd_level":1021.09,"humidity":71},"wind":{"speed":1.98,"deg":173.003},"clouds":{"all":0},"dt":1428833796,"id":3031005,"name":"Bourges","cod":200}

    C'est chouette me diras-tu, mais tu voulais l'afficher dans une jolie page... alors ajoutons un moteur de template et plutot que de retourner un objet json, on va renvoyer du html

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    // app.js
    var express = require('express');
    var http = require('http');
    var path = require('path');
     
    var app = express();
     
    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'ejs');
     
    app.get('/', function (req, res) {
        var openWeatherMapURL = 'http://api.openweathermap.org/data/2.5/weather?q=Bourges,France&lang=fr&units=metric';
        require('request').get(openWeatherMapURL, function (err, response, body) {
            if (err) throw err;
            if (!err && response.statusCode == 200) {
     
                var info = JSON.parse(body);
                res.render('index', {
                    info: info
                });
     
            }
        });
    });
     
    http.createServer(app).listen(3000, function () {
        console.log('Le serveur ecoute sur le port 3000');
    });
    1. on charge le module path, une des nombreuses fonctions utilitaires de node; un coup d'oeil à la doc sibylline https://nodejs.org/api/path.html
    2. grace à app.set() on spécifie dans la variable 'views' le chemin du dossier racine où l'on va mettre nos templates. ce dossier va s'appeler ... views...
    3. grace à app.set() on spécifie dans la variable 'views engine' le ... moteur de template que l'on souhaite utiliser, soit 'ejs' dans ton cas (perso je préfére jade, question de goût je suppose)
    4. on parse notre body pour en faire un objet javascript
    5. enfin, on utilise .render pour indiquer que l'on souhaite renvoyer le contenu du fichier index du dossier views en passant l'objet info en paramétre


    on crée à coté de notre fichier app.js un dossier views, dans lequel on place notre template index.ejs
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    // views/index.ejs
    <!DOCTYPE html>
    <html>
    <head lang="fr">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <p>la météo sur <%= info.name %> est <%= info.weather[0].description %> avec une température de <%= info.main.temp %>°c</p>
    </body>
    </html>
    y'a plus qu'à allez via ton navigateur à http://127.0.0.1:3000/, et tu obtient une page toute moche avec ta météo

    bon, l'exemple n'est pas affriolant, mais permet de mettre en place les bases, de mettre en avant la notion de modules, car par la suite on va en ajouter du module et de la fonction! express est inspiré de sinatra http://www.sinatrarb.com/, soit un micro-framework, et il n'y a rien de magique.

    On va voir du un peu plus lourd, avec le moteur de blog et la gestion de la bdd mongo, l'ajout de css et des pré-processeur, le module debug, les sessions, le parsage des formulaires, la gestion des erreurs, et peut-etre avant ca je ferais un point sur la fonction require.

    et je pense garder le lecteur de rss pour la fin, voir en exercice dirigé. Finalement, ce n'est pas tellement ce tuto qui me semble important, mais tout le blabla avant, en particulier sur la notion de callback et d'asynchronicité. C'est le moment d'expérimenter et de poser des questions sur le sujet.

  15. #15
    Membre habitué Avatar de lostsoul
    Homme Profil pro
    Rédacteur web, blogueur, développeur web junior
    Inscrit en
    Novembre 2003
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Rédacteur web, blogueur, développeur web junior
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2003
    Messages : 759
    Points : 184
    Points
    184
    Par défaut
    Ca fonctionne bien ;-)
    J'ai même ajouté quelques infos de météo, l'icône et arrondi la température.

    C'est assez simple pour le moment effectivement. Mais c'est bien, comme ça, j'arrive à comprendre comment ça fonctionne, c'est déjà bien intéressant.

    Je vais relire les posts depuis le début, pour vérifier que je comprends bien tout.
    ANDRE Ani
    GNU/Linux et Informatique Libre
    https://andre-ani.fr

  16. #16
    Membre habitué Avatar de lostsoul
    Homme Profil pro
    Rédacteur web, blogueur, développeur web junior
    Inscrit en
    Novembre 2003
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Rédacteur web, blogueur, développeur web junior
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2003
    Messages : 759
    Points : 184
    Points
    184
    Par défaut
    On pourrait partir d'un projet Express pour expliquer l'arborescence et les fichiers, à quoi ils servent, ce qu'on met dedans ?

    /server/controllers/index.js
    /routes.js
    /server/models
    /views

    Pour avoir un site avec plusieurs pages, en passant des infos différentes à chaque pages (res, render, avec des variables).

    Ensuite, quelques questions :

    Pourquoi un script Vanilla ?
    Expliciter les middlewares connect ?
    Qu'est-ce que les helper ?

    Et si j'ai bien compris, une fonction synchrone s'exécute dès qu'elle est apellée, alors qu'un fonction asynchrone doit attendre que la précédente soit terminée (donc elle est bloquante), c'est bien cela ?

    Voila quelques questions donc. Il faudrait voir tout en faisant le site je suppose pour expliquer tout ça.
    ANDRE Ani
    GNU/Linux et Informatique Libre
    https://andre-ani.fr

  17. #17
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    154
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2009
    Messages : 154
    Points : 233
    Points
    233
    Par défaut
    On pourrait partir d'un projet Express pour expliquer l'arborescence et les fichiers, à quoi ils servent, ce qu'on met dedans ?
    Comme tu veux, mais jusque là, j'essaye au contraire de ne pas te noyer sous les fonctionnalités et de construire au fur et à mesure, jusqu'à ce que l'on arrive à la configuration par défaut de express. Mais je comprends que ce soit frustrant, surtout que je vais trés, trés lentement

    Pour avoir un site avec plusieurs pages, en passant des infos différentes à chaque pages (res, render, avec des variables).
    là je peux te répondre tout de suite...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
     
    app.get('/', function(req, res) { // GET http://www.test.fr/
      res.render('index', {foo: 'bar', toto: 'tata'}); // renvoi  le template views/index avec toutes les variables que tu veux en paramétre
    });
     
    app.get('/toto', function(req, res) { // GET http://www.test.fr/toto
      res.render('toto/index', {foo: 'bar', toto: 'tata'}); // renvoi  le template views/toto/index avec toutes les variables que tu veux en paramétre
    });
     
    app.post('/toto', function(req, res) { // POST http://www.test.fr/toto pour envoyer les données d'un formulaire par exemple
     
      var formValue = req.params.body; // les valeurs du formulaires
      console.log(formValue); // traitement des valeurs du formulaire
      res.render('back'); // retourne à la page précédente
    });
     
    app.get('/toto/list', function(req, res) { // GET http://www.test.fr/toto/list
      var list = ['un', 'deux', 'trois']; // fausse bdd
      res.render('toto/list', {liste: list}); // renvoi  le template views/toto/list avec la liste en parametre
    });
     
    ... et ainsi de suite
    Pourquoi un script Vanilla ?
    Parce que c'est un peu dommage d'embarquer jquery ou un framework complet pour faire un simple GET sur une url et l'afficher.

    Expliciter les middlewares connect ?
    lapin compris la question ?!?

    Qu'est-ce que les helper ?
    Les aides en bon françois juste pour dire que ce sont des simplifications, des fonctions qui te facilite les choses plutôt que ce soit toi qui le fasse, par exemple, renvoyer res.json(taVariable) t'évite d'avoir à faire un JSON.stringify(taVariable) avant un res.send. C'est tout.

    Et si j'ai bien compris, une fonction synchrone s'exécute dès qu'elle est apellée, alors qu'un fonction asynchrone doit attendre que la précédente soit terminée
    oui, mais ce n'est qu'une partie de la problématique

    (donc elle est bloquante), c'est bien cela ?
    pas du tout

    prenons l'image d'un restaurant avec plusieurs cuisiniers mais un seul serveur pour prendre les commandes...

    • le serveur prends toutes les commandes les unes à la suite des autres, mais n'attends pas que chaque plat soit prêts et de l'avoir servit avant de prendre une nouvelle commande... c'est la boucle évenementielle. le serveur attends un évènement quelconque, un nouveau client, une nouvelles commandes, un plat prêt à la cuisine...
    • les cuistots s'organisent en se répartissant les plats, mais chaque plat à bien sur un temps de cuisson et de préparation différente. Ils peuvent aussi ce gêner car pas assez de place dans le four pour toutes les commandes en même temps, et s'ils essayent de gérer chaque commandes dans l'ordre d'arrivé, dés qu'un plat est prêt, ils le passe au serveur pour qu'il le serve au client. Si le four est plein, il prépare d'autres plat pendant ce temps, les types ne regardent pas le four comme des c** (sauf s'il n'ont qu'un plat à préparer biensur) C'est une gestion asynchrone.
    • Imaginons un client mécontent à qui l'on doit refaire le plat immédiatement... le serveur donne l'info en cuisine, qui fait passer ce plat avant tous les autres, et en plus le serveur attends dans les cuisines que le plat en question soit prêt avant de retourner en salle... tous les autres clients attendent leurs plats plus longtemps que prévu, mais en plus ils ne peuvent plus passer de nouvelles commandes, et de nouveaux client attendent à dans l'entrée du restaurant qu'un serveur s'occupe d'eux pour les placer et prendre leur commande... le client mécontent est une requête synchrone, et c'est ce qu'il faut à tous prix éviter!

  18. #18
    Membre habitué Avatar de lostsoul
    Homme Profil pro
    Rédacteur web, blogueur, développeur web junior
    Inscrit en
    Novembre 2003
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Rédacteur web, blogueur, développeur web junior
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2003
    Messages : 759
    Points : 184
    Points
    184
    Par défaut
    Merci pour toutes ces explications, ça aide bien.

    Je vais me pencher un peu sur Vanilla alors, voir un peu plus ce qu'on peut faire avec, si ça peut être utile pour certaines choses.

    Bon, j'avoue, j'ai tendance à mettre la charrue avant les boeufs, et je manque un peu de patience ;-p

    Comme j'ai déjà testé de petits projets avec Express et ses différents fichiers, c'est pour ça que je voulais partir de ça.

    Mais il vaut mieux éviter de bruler les étapes, et puis, c'est toi le prof ;-)
    ANDRE Ani
    GNU/Linux et Informatique Libre
    https://andre-ani.fr

  19. #19
    Membre actif
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    154
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Vienne (Limousin)

    Informations forums :
    Inscription : Avril 2009
    Messages : 154
    Points : 233
    Points
    233
    Par défaut
    Merci pour toutes ces explications, ça aide bien.
    J’espère simplement que mon image te convient parce que c'est fondamental, n’hésite pas à la reformuler, à la triturer dans tous les sens, parce que contrairement à ce que tu dis plus bas, je ne suis pas prof et la pédagogie ne m'est pas inné de plus tout est facile quand on à compris, du coup, je ne suis pas toujours sur d'avoir bien transmis mon message.

    Je vais me pencher un peu sur Vanilla alors, voir un peu plus ce qu'on peut faire avec, si ça peut être utile pour certaines choses.
    Pour qu'il n'y ai pas de malentendu, quand on parle de JavaScript vanilla, on parle du JavaScript de base, natif, pas de http://vanilla-js.com/.

    Bon, j'avoue, j'ai tendance à mettre la charrue avant les boeufs, et je manque un peu de patience ;-p
    Je te rassure, j'ai fais tout pareil, et j'ai perdu beaucoup de temps. C'est bien pour ça que je me suis lancé dans ce cours/tuto, pour en faire gagner (j’espère) à d'autres.

    Comme j'ai déjà testé de petits projets avec Express et ses différents fichiers, c'est pour ça que je voulais partir de ça.
    les fichiers d'express n'ont aucunes importance, d'abord, parce que express n'oblige à rien, contrairement à Sails.js ou Meteor.js par exemple, mais si tu fais un jour du Meteor.js, ce seront toujours les mêmes concepts, mais pas la même forme ni les mêmes fichiers. D'où l’intérêt de manipuler et comprendre les concepts clé, plutôt que d'apprendre à manipuler un framework en particulier.


    Si non, encore une fois, je suis désolé d'être aussi long. Je ne n'ai pas toujours le temps et les conditions pour te faire un bout du tuto, du coup cela traine. que cela ne t'empeche pas de bidouiller de ton coté . Le but est aussi de pouvoir profiter des interrogations d'un débutant en direct pour faire un cours/tuto le mieux foutu possible.

  20. #20
    Membre habitué Avatar de lostsoul
    Homme Profil pro
    Rédacteur web, blogueur, développeur web junior
    Inscrit en
    Novembre 2003
    Messages
    759
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Cher (Centre)

    Informations professionnelles :
    Activité : Rédacteur web, blogueur, développeur web junior
    Secteur : Conseil

    Informations forums :
    Inscription : Novembre 2003
    Messages : 759
    Points : 184
    Points
    184
    Par défaut
    Ok pour javascript vanilla, c'est pour ça que j'ai préféré poser la question, pour savoir ce que c'était vraiment.

    Oui, je pense que ce tuto pourra servir à d'autres, et faire gagner du temps en apréhendant bien les bases.

    Dac pour Express, je croyais que c'étais, plus ou moins, un modèle à suivre, mais donc, en fait, c'est juste une façon de faire parmi d'autres alors. C'est bon à savoir. Comme j'ai déjà fais quelques essais, je me suis basé à chaque fois sur l'arborescence d'Express avec Express generator. Ca permet au moins d'organiser ses fichiers comme il faut.

    Ne t'excuses pas de manquer de temps, ce n'est pas grave (et je sais ce que c'est, les journées sont trop courtes pour moi aussi). C'est déjà bien de faire ce que tu fais et je t'en remercie ;-)
    Oui, je continue à bidouiller dans mon coin en attendant la suite de ton tuto ;-)
    ANDRE Ani
    GNU/Linux et Informatique Libre
    https://andre-ani.fr

Discussions similaires

  1. Comment afficher deux images avec Node js ?
    Par keokaz dans le forum NodeJS
    Réponses: 5
    Dernier message: 03/10/2014, 06h11
  2. Ouvrir/afficher un fichier avec son logiciel par défaut
    Par Alain P. dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 20/06/2009, 18h47
  3. Comment afficher du texte avec swing ?
    Par meda dans le forum AWT/Swing
    Réponses: 8
    Dernier message: 27/10/2004, 14h35
  4. Afficher une image avec swing
    Par arnonote dans le forum AWT/Swing
    Réponses: 11
    Dernier message: 07/08/2004, 12h10
  5. PL/SQL - Comment afficher une image avec HTP ?
    Par patmaba dans le forum PL/SQL
    Réponses: 2
    Dernier message: 08/07/2004, 09h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo