Je crée une application météo pour m'entraîner à utiliser express et ejs. J'utilise app.get pour demander des informations à l'API de darkSky. Cet appel est effectué une fois et il est réussi, je suis également en mesure de le restituer dans mon fichier index.ejs.

J'aimerais ajouter une fonction d'horloge en temps réel à l'aide de moment.js appelée à l'aide de setInterval. (c'est la fonction commentée 'updateTime()')

Étant donné que je ne veux pas rappeler l'API météo à chaque fois que l'horloge serait mise à jour, je pense qu'elle doit être en dehors de l'appel app.get.

Je ne sais pas comment configurer cela, car il semble que je ne puisse pas utiliser la manipulation DOM pour ajouter la fonction d'horloge.

Existe-t-il un moyen d'obtenir du contenu dynamique dans mes ejs, distinct de mon appel API ?

(ps - l'extrait de code ne fonctionnera pas, je voulais juste ajouter le code pour un point de référence)

const path = require('path')
const express = require('express')
const request = require('request')
const moment = require('moment')

const app = express();
const publicDirectoryPath = path.join(__dirname, '/public')

app.use(express.static(publicDirectoryPath))
app.set('view engine', 'ejs');

let sush = 'e20fe780791cad1d4d4d7b8484f970a5';
let lat = 39.892692;
let lng = -86.290568;

let apiUrl = `https://api.darksky.net/forecast/${sush}/${lat},${lng}`;

// function updateTime() {
//     let dayTime = moment().format("dddd h:mma")
//     console.log(dayTime)
//  }
//  setInterval(updateTime, 5000)

// app.use("/", function (req, res){
    let dayTime;
    function updateTime() {
        dayTime = moment().format("dddd h:mma")
        console.log(dayTime)
        return dayTime
     }
     setInterval(updateTime, 5000)
    //  res.render('index.ejs', {dayTime:dayTime})
// })

app.get('/', function (req, res) {

    request(apiUrl, function (error, response, body) {

        if (error){
            console.log('hey, hi, i didnt work - am i internet?')
        } 
        
        weather_json = JSON.parse(body);

        let dataDayThree = weather_json.daily.data[2].time;
        let dataDayFour = weather_json.daily.data[3].time;
        let dataDayFive = weather_json.daily.data[4].time

        let daytwo = moment.unix(weather_json.daily.data[1].time).format("dddd")
        let daythree = moment.unix(dataDayThree).format("dddd")
        let dayfour = moment.unix(dataDayFour).format("dddd")
        let dayfive = moment.unix(dataDayFive).format("dddd")

        let iconCurrentlyOut = weather_json.currently.icon;
        let iconTodayOut = weather_json.daily.data[0].icon;
        let iconTomorrowOut = weather_json.daily.data[1].icon;
        let iconDay3Out = weather_json.daily.data[2].icon;
        let iconDay4Out = weather_json.daily.data[3].icon;
        let iconDay5Out = weather_json.daily.data[4].icon;

        function iconLooper(x){

            switch (x) {
                case 'rain':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--lV_oG1pX--/v1515194565/rainy-6_pzlrlc.svg";
                    break;
                case 'snow':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--EsqjgOhi--/v1515194606/snowy-6_zl9kwx.svg";
                    break;
                case 'clear-day':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s---6vDoixr--/v1515194528/day_shry4k.svg";
                    break;
                case 'clear-night':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--CxSp0zXi--/v1515194530/night_quuh8p.svg";
                    break;
                case 'sleet':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--yeTLFcMd--/v1515194570/rainy-7_sdbkyl.svg";
                    break;
                case 'wind':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--ivgWegRI--/v1515194500/cloudy_vqbnvk.svg"
                    break;
                case 'fog':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--ivgWegRI--/v1515194500/cloudy_vqbnvk.svg"
                    break;
                case 'cloudy':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--ivgWegRI--/v1515194500/cloudy_vqbnvk.svg";
                    break;
                case 'partly-cloudy-day':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--pkzBuC_i--/v1515194500/cloudy-day-1_n3vykl.svg";
                    break;
                case 'snow':
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--DdrT7Iph--/v1515194500/cloudy-night-1_ro8fb5.svg";
                    break;
                default:
                    console.log('i dont know whats goin on')    
                    iconCurrently = "https://res.cloudinary.com/raphaeladdile/image/upload/s--ivgWegRI--/v1515194500/cloudy_vqbnvk.svg";
                    defaultTest = "i am an unkno"
            }
            return iconCurrently
        }

          ///////////////////////////////////////////////////////////////////////////////////////////////
         // if default in switch is activated add in what the actual weather is, like 'thunderstorms' //
        //////////////////////////////////////////////////////////////////////////////////////////////

        // function updateTime() {
        //     dayTime = moment().format("dddd h:mma")
        //     console.log(dayTime)
        //     return dayTime
        //  }
        //  setInterval(updateTime, 5000)

        let weather = {
            // date & time
            //dayTime: updateTime(),
            date: moment().format("MMM Do. YYYY"),
            // current
            currentTemp: Math.round(weather_json.currently.temperature),
            summary: weather_json.currently.summary,
            currentIcon: iconLooper(iconCurrentlyOut),
            currentFeelLike: Math.round(weather_json.currently.apparentTemperature),
            currentHumidity: Math.round(100 * (weather_json.currently.humidity)),
            dailySummary: weather_json.daily.summary,
            todayHi: Math.round(weather_json.daily.data[0].temperatureMax),
            todayLo: Math.round(weather_json.daily.data[0].temperatureMin),
            todayIcon: iconLooper(iconTodayOut),
            // tomorrow
            dayTwo: daytwo,
            dayTwoHi: Math.round(weather_json.daily.data[1].temperatureMax),
            dayTwoLo: Math.round(weather_json.daily.data[1].temperatureMin),
            dayTwoIcon: iconLooper(iconTomorrowOut),
            // day three
            dayThree: daythree,
            dayThreeHi: Math.round(weather_json.daily.data[2].temperatureMax),
            dayThreeLo: Math.round(weather_json.daily.data[2].temperatureMin),
            dayThreeIcon: iconLooper(iconDay3Out),
            // day four
            dayFour: dayfour,
            dayFourHi: Math.round(weather_json.daily.data[3].temperatureMax),
            dayFourLo: Math.round(weather_json.daily.data[3].temperatureMin),
            dayFourIcon: iconLooper(iconDay4Out),
            // day five
            dayFive: dayfive,
            dayFiveHi: Math.round(weather_json.daily.data[4].temperatureMax),
            dayFiveLo: Math.round(weather_json.daily.data[4].temperatureMin),
            dayFiveIcon: iconLooper(iconDay5Out)
        }

        let weatherData = {
            weather: weather
        }

        res.render('index', weatherData)
    })

});

app.listen(8000);
<!DOCTYPE html>
    <head>
        <title>weatherApp</title>
        <link rel="stylesheet" href="/css/style.css">
    </head>
    <body>
    <div id="container">

    <!-- header 
        <div class="header">
            <button class="refresh-btn" onClick="window.location.reload()">Refresh</button>
        </div>
        -->

        <div class="row">
        <!-- icon -->
            <div class="column iconColumn">        
                <img class="currentWeatherIcon" src='<%=weather.currentIcon%>' />
            </div>

        <!-- descriptions -->
            <div class="column description">
            <button class="refresh-btn" onClick="window.location.reload()">Refresh</button>
                <h5><%=weather.currentTemp%>&deg;F  |  <%=weather.summary%></h5> 
                <h5>Feels like <%=weather.currentFeelLike%>&deg; F | humidity <%=weather.currentHumidity%>%</h5>
            </div>
        </div>

        <h6 class="daySummary"><%=weather.dailySummary%></h6>
    <!-- table -->
            <table>
            <th>Today</th>
            <th><%=weather.dayTwo%></th>
            <th><%=weather.dayThree%></th>
            <th><%=weather.dayFour%></th>
            <th><%=weather.dayFive%></th>
            <tr>
              <td>
                <img src='<%=weather.todayIcon%>' />
                  <div class="hi-lo"><%=weather.todayHi%>&deg;-<%=weather.todayLo%>&deg;</div>
              </td>
              <td>
              <img src='<%=weather.dayTwoIcon%>' />
                  <div class="hi-lo"><%=weather.dayTwoHi%>&deg;-<%=weather.dayThreeLo%>&deg;</div>
              </td>
              <td>
              <img src='<%=weather.dayThreeIcon%>' />
                  <div class="hi-lo"><%=weather.dayThreeHi%>&deg;-<%=weather.dayThreeLo%>&deg;</div>
              </td>
              <td>
              <img src='<%=weather.dayFourIcon%>' />
                  <div class="hi-lo"><%=weather.dayFourHi%>&deg;-<%=weather.dayFourLo%>&deg;</div>
              </td>
              <td>
              <img src='<%=weather.dayFiveIcon%>' />
                  <div class="hi-lo"><%=weather.dayFiveHi%>&deg;-<%=weather.dayFiveLo%>&deg;</div>
              </td>
        
            </tr>
          </table>
</div>
        <script type="text/javascript" src="app.js"></script>
    </body>
</html>
2
Nathan 15 mars 2019 à 16:31

2 réponses

Meilleure réponse

Pour afficher une simple horloge en utilisant le javascript client, cela n'a rien à voir avec le rendu du serveur. Vous pouvez simplement exécuter du code javascript dans votre fichier ejs dans les balises script. Consultez cet exemple simple que vous pouvez trouver sur https://www.w3schools.com/js/ :

 <!DOCTYPE html>
    <html>
    <head>
    
    </head>
    
    <body onload="startTime()">
    <h3> Here is a simple clock.</h3>
    <div id="clock"></div>
    <script>
    function startTime() {
      var today = new Date();
      var h = today.getHours();
      var m = today.getMinutes();
      var s = today.getSeconds();
      m = checkTime(m);
      s = checkTime(s);
      document.getElementById('clock').innerHTML =
      h + ":" + m + ":" + s;
      var t = setTimeout(startTime, 500);
    }
    // add zero in front of numbers < 10
    function checkTime(i) {
      if (i < 10) {i = "0" + i};  
      return i;
    }
    </script>
    </body>
    </html>
1
dimitris tseggenes 15 mars 2019 à 15:35

Pour effectuer des manipulations DOM, vous devez inclure un fichier JS dans le code HTML, comme vous l'avez fait avec CSS. Remplacez votre <head> par celui-ci

<head>
    <title>weatherApp</title>
    <link rel="stylesheet" href="/css/style.css">
    <script src="/js/script.js">
</head>

Créez le répertoire js près de css et le fichier script.js dedans, le javascript que vous y ajoutez peut être exécuté à partir de votre modèle ejs.

1
Matas 15 mars 2019 à 13:53