简体   繁体   中英

NodeJS no data returned from function

I am working on a simple weather application which uses mysql database that has just the names of the cities. Than i query the database for all the names and i send request to openweathermap's API for the weather info.

function getCities() {
  con.connect();
  con.query(('SELECT city_name FROM cities'), (err, res) => {
    console.log(res);
    getWeather(cities);
  });
};

async function getWeather(cities) {
  var data = [];
  for (var i = 0; i < cities.length; i++) {
    var url = `http://api.openweathermap.org/data/2.5/weather?q=${cities[i].city_name}&units=metric&appid=271d1234d3f497eed5b1d80a07b3fcd1`;
    await request(url, (err, res, body) => {
      var json = JSON.parse(body);
      var weather = {
        city: json.name,
        temperature: json.main.temp,
        description: json.weather[0].description,
        icon: json.weather[0].icon
      };
      data.push(weather);
    });
  }
  console.log(data);
}

The getCities() function works as expected and returns all the cities but the errors happen in the getWeather function particulary these errors:

Desktop/WeatherApp/node_modules/request-promise-core/lib/plumbing.js:130
            throw thrownException;
            ^

TypeError: Cannot read property 'temp' of undefined
    at Request.request [as _rp_callbackOrig] (/home/kristijan/Desktop/WeatherApp/app.js:60:41)
    at Request.plumbing.callback (/home/kristijan/Desktop/WeatherApp/node_modules/request-promise-core/lib/plumbing.js:76:39)
    at Request.RP$callback [as _callback] (/home/kristijan/Desktop/WeatherApp/node_modules/request-promise-core/lib/plumbing.js:46:31)
    at Request.self.callback (/home/kristijan/Desktop/WeatherApp/node_modules/request/request.js:185:22)
    at Request.emit (events.js:182:13)
    at Request.<anonymous> (/home/kristijan/Desktop/WeatherApp/node_modules/request/request.js:1161:10)
    at Request.emit (events.js:182:13)
    at IncomingMessage.<anonymous> (/home/kristijan/Desktop/WeatherApp/node_modules/request/request.js:1083:12)
    at Object.onceWrapper (events.js:273:13)
    at IncomingMessage.emit (events.js:187:15)
    at endReadableNT (_stream_readable.js:1094:12)
    at process._tickCallback (internal/process/next_tick.js:63:19)

As far as i understood it is jumping the inside of the arrow function before getting the result from the API?

await only waits for the async operation if the function result you are awaiting returns a promise. The request() function does not return a promise (it works with the callback you are passing it) and thus await does not wait for that result. You can use the request-promise library instead which does return a promise and you do not pass it a callback.

Here's an example:

const rp = require('request-promise');

async function getWeather(cities) {
  let data = [];
  for (let i = 0; i < cities.length; i++) {
    let url = `http://api.openweathermap.org/data/2.5/weather?q=${cities[i].city_name}&units=metric&appid=271d1234d3f497eed5b1d80a07b3fcd1`;
    let body = await rp(url);
    let json = JSON.parse(body);
    let weather = {
        city: json.name,
        temperature: json.main.temp,
        description: json.weather[0].description,
        icon: json.weather[0].icon
    };
    data.push(weather);
  }
  console.log(data);
}

Note, you can also let the request API parse the JSON for you automatically:

const rp = require('request-promise');

async function getWeather(cities) {
  let data = [];
  for (let i = 0; i < cities.length; i++) {
    let url = `http://api.openweathermap.org/data/2.5/weather?q=${cities[i].city_name}&units=metric&appid=271d1234d3f497eed5b1d80a07b3fcd1`;
    let json = await rp({uri:url, json: true});
    let weather = {
        city: json.name,
        temperature: json.main.temp,
        description: json.weather[0].description,
        icon: json.weather[0].icon
    };
    data.push(weather);
  }
  console.log(data);
}

EDIT Jan, 2020 - request() module in maintenance mode

FYI, the request module and its derivatives like request-promise are now in maintenance mode and will not be actively developed to add new features. You can read more about the reasoninghere . There is a list of alternatives in this table with some discussion of each one. I have been using got() myself and it's built from the beginning to use promises and is simple to use.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM