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.