0

So I want to require this function from another file and use it in main.js. But I keep getting undefined. Now that doesn't surprise me. Because with console.log I see prepareWeather() has finished before getWeather() has finished. But it also stays empty/undefined.

The function needs to update the variable globalWeather every 15 minutes in main.js. So it's updated with the latest weather info. I tried everything with async/await and .next() but I have absolutley no idea what I'm doing anymore. I feel pretty lost.

I stripped the code down to only the necessary to make it readable. That's also the reason I want getWeather() to be in a separate file. It is pretty long.

Can someone tell me how to make this work? And furthermore, explain me why this doesn't work?

main.js

const getWeather = require("./functions/getweather.js");
let globalWeather = {};

prepareWeather();
async function prepareWeather() {
  console.log(`a: ${Date.now()}`);
  globalWeather = await getWeather(); //return object
  console.log(`b: ${Date.now()}`);
  console.log(globalWeather);
  console.log(`c ${Date.now()}`);
  setTimeout(prepareWeather, 10000); //900000 when it works
}

getweather.js

module.exports = exports = async function getWeather(){

  const request = require("request");
  const key = `XXX`;
  const lat = `10.01`;
  const lon = `10.01`;
  const units = `metric`;

  let url = `http://api.openweathermap.org/data/2.5/weather`+
            `?APPID=`+key+
            `&lat=`+lat+
            `&lon=`+lon+
            `&units=`+units;

  console.log(`1 ${Date.now()}`);
  await request({
    url: url,
    json: true
  }, await function (error, response, body) {

    console.log(`2 ${Date.now()}`);

    if (!error && response.statusCode === 200) {

      console.log(`3 ${Date.now()}`);

      let wobj = body;
      let id = wobj.weather[0].id;

      if (id === 200 || id === 201) {
        wobj.emoji = `⛈`;
      } else if(id === 300) {
        wobj.emoji = ``; 
      }

      console.log(`4 ${Date.now()}`)

      //console.log(wobj);
      return wobj;
      }
  });
}

console:

a: 1520974253102
1 1520974253103
b: 1520974253125
undefined //This is console.log(globalWeather);
c 1520974253125
2 1520974253159
3 1520974253159
4 1520974253159

//console.log(wobj); in getweather.js does eventually return an object in my console. But not in main.js.

Hedva
  • 317
  • 1
  • 3
  • 15
  • Why aren't you using `setInterval()` to execute something every 15 minutes? – Barmar Mar 13 '18 at 21:30
  • Well the problem is; I can make it work when all the code is in main.js. Instead of `return wobj` an object, i just `globalWeather = wobj`. But when I try to cut it in multiple files (getweather.js), I can't get the `globalWeather` variable updated. The actual getweather.js is much longer. So I really want to have it in multiple files – Hedva Mar 13 '18 at 21:39
  • And If I use `globalWeather = getWeather()` (so no await). It returns `Promise { }` – Hedva Mar 13 '18 at 21:42
  • I'm not really an expert in ES6 modules, but I'm thinking something like `const getWeather = require(...); setInterval(getWeather, 900000);` – Barmar Mar 13 '18 at 21:46
  • The problem with that is that I can't assign the `globalWeather` variable. I can't do `globalWeather = setInterval(getWeather, 900000);` Somehow I need to pass the data from `return wobj` into `globalWeather`. But no luck so far – Hedva Mar 13 '18 at 21:55
  • If you're using promises, it should be `resolve(wobj)` and `.then(w => globalWeather = w);` – Barmar Mar 13 '18 at 21:58
  • I just lost you. I used async/await in getweather.js, which result in Promise { } if I call the function directly in console. Everything I do just results in `undefined`. Thanks for you help anyway. I probably should get some sleep – Hedva Mar 13 '18 at 22:26
  • 1
    Perhaps you need to read this: https://stackoverflow.com/questions/23667086/why-is-my-variable-undefined-after-i-modify-it-inside-of-a-function-asynchron?newsletter=1&nlcode=97716%7c4ba7 – Barmar Mar 13 '18 at 22:37
  • I really want to thank you by providing that link! Now I do understand and I got it working. I really appreciate your help! Thanks! – Hedva Mar 15 '18 at 09:32

1 Answers1

0

So I share my solution here for if anyway else get here with the same problem. The link Barmar provided in the comments explains it really good.

So in main.js:

//Global var  
let globalWeather = {};

//Calling the function at startup 
getWeather(function(result) {
  globalWeather = result;
})}, 10000

//Call the function after 15 minutes 
// and every 15 minutes after that
setInterval(function() {
  getWeather(function(result) {
    globalWeather = result;
  })}, 900000
);

In getweather.js:

//Pretty much the same only start with:
module.exports = exports = function getWeather(callback){

//And instead of return wobj:
callback(wobj);
Hedva
  • 317
  • 1
  • 3
  • 15