Getting values from http request in nodejs
var latLon = "40.8,-77.8"; //Lat/lon
var cityCode = ""; //City code
var cityName = "";
var latLongCityCodeURL = ("http://dataservice.accuweather.com/locations/v1/cities/geoposition/search?apikey=" + weatherKey + "&q=" + latLon);
//Current Conditions Vars
var ccWeatherText = ""; //Text for weather at location
var ccTemp = 0; //Degrees Farenheit
var ccIcon = 0; //weather icon number https://developer.accuweather.com/weather-icons
var ccURL = "test"; //URL for get
//12 hour forecast Conditions Vars
//5 day forecast conditions Vars
//Get city code
http.get(latLongCityCodeURL, (resp) => {
var that = this;
resp.on("data", (chunk) => {
var result = JSON.parse(chunk);
var cityCode = result.Key;
var cityName = result.EnglishName;
console.log(cityCode + " " + cityName);
that.cityName = cityName;
that.cityCode = cityCode;
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
console.log(cityCode + " " + cityName);
So my issue is, I am making an http request using require('http'), what I want to do is parse the data and store it in my global variables so that I can use them for other requests. I have tried using var that=this
and I have tried just assigning my global variables to the data. I am not sure how to do it, i just keep getting undefined. I know it has something to do with ASYNC and also something to do with the scope. Please help
6 answers
-
answered 2018-05-16 06:24
scetiner
Your code block runs in a synchronized way and console.log part hits just after http.get call. The thing is http.get is an async function and its callback part will be called future ticks of NodeJS when your response has arrived.
-
answered 2018-05-16 06:27
Arif Khan
You can use
Promise
to make http request, here is code that may help youconst httpGet = url => { return new Promise((resolve, reject) => { http.get(url, res => { let body = ''; res.on('data', chunk => body += chunk); res.on('end', () => { try { body = JSON.parse(body); } catch (err) { reject(new Error(err)); } resolve({ cityCode: body.Key, cityName: body.EnglishName }); }); }).on('error', reject); }); }; httpGet(latLongCityCodeURL).then(data => { console.log(data.cityCode + " " + data.cityName); }).catch(err => console.log('Got error ', err));
-
answered 2018-05-16 06:28
cricket_007
You must wait for the response, then send the other requests or log into. The scope isn't really the issue here, it's the order of operations that you're missing. You define a variable, then wait for a HTTP request, meanwhile you're immediately logging a value, then the request finishes (or times out or other error), and you can log again the value - at which point you see data.
In other words, to fix the issue, other requests must be made from within a function of
resp.on("end"
, which says when you've finished getting all data chunksAnd by "within", the code can still be in a separate method, outside those brackets, but you must call that particular function from within that response body.
You should pass such asynchronous returned data through parameter variables, not update some external, global state in most cases
-
answered 2018-05-16 06:30
Terry Lennox
You can save your result to a variable at various levels of scope.. just remember that most i/o calls in Node.js are asynchronous. Here's an example:
var latLon = "40.8,-77.8"; //Lat/lon var cityCode = ""; //City code var cityName = ""; var latLongCityCodeURL = ("http://dataservice.accuweather.com/locations/v1/cities/geoposition/search?apikey=" + weatherKey + "&q=" + latLon); //Current Conditions Vars var ccWeatherText = ""; //Text for weather at location var ccTemp = 0; //Degrees Farenheit var ccIcon = 0; //weather icon number https://developer.accuweather.com/weather-icons var ccURL = "test"; //URL for get var savedResult = null; //Get city code http.get(latLongCityCodeURL, (resp) => { var jsonData = ''; resp.on("data", (chunk) => { jsonData += chunk; }); resp.on("end", () => { savedResult = JSON.parse(jsonData); }); }).on("error", (err) => { console.log("Error: " + err.message); }); // Display saved result once available. setTimeout(displaySavedResult, 2000); function displaySavedResult() { if (!savedResult) { console.log('Last result is null!'); } else { console.log('Last result: City Code: ' + savedResult.Key + " Name" + savedResult.EnglishName); console.log('Last result (all properties): ', JSON.stringify(savedResult, null, 2)); } }
-
answered 2018-05-16 06:35
anshuVersatile
var http = require('http'); var latLon = "40.8,-77.8"; //Lat/lon var cityCode = ""; //City code var cityName = ""; var latLongCityCodeURL = ("http://dataservice.accuweather.com/locations/v1/cities/geoposition/search?apikey=" + "fmKWSgaG5EAA0diCP2lSREEOYG6PC5q9" + "&q=" + latLon); var that; //Current Conditions Vars var ccWeatherText = ""; //Text for weather at location var ccTemp = 0; //Degrees Farenheit var ccIcon = 0; //weather icon number https://developer.accuweather.com/weather-icons var ccURL = "test"; //URL for get //12 hour forecast Conditions Vars //5 day forecast conditions Vars //Get city code getWeather = url => { return new Promise((resolve, reject) => { http.get(url, res => { let body = ''; res.on('data', chunk => resolve(JSON.parse(chunk))); }).on('error', reject); }); }; getWeather(latLongCityCodeURL).then( weather => { console.log(weather.Key + " " + weather.EnglishName); })
-
answered 2018-05-16 06:35
owaishanif786
var latLon = "40.8,-77.8"; var latLongCityCodeURL = ("http://dataservice.accuweather.com/locations/v1/cities/geoposition/search?apikey=" + weatherKey + "&q=" + latLon); //Current Conditions Vars var ccWeatherText = ""; //Text for weather at location var ccTemp = 0; //Degrees Farenheit var ccIcon = 0; //weather icon number https://developer.accuweather.com/weather-icons var ccURL = "test"; //URL for get //12 hour forecast Conditions Vars //5 day forecast conditions Vars //Get city code function getCityCode(latLongCityCodeURL){ return new Promise((resolve, reject) => { http.get(latLongCityCodeURL, (resp) => { resp.on("data", (chunk) => { var result = JSON.parse(chunk); var cityCode = result.Key; var cityName = result.EnglishName; resolve({cityCode, cityName}); }); }).on("error", (err) => { reject(err); console.log("Error: " + err.message); }); }) } getCityCode(latLongCityCodeURL) .then((result) => { console.log(result.cityCode, result.cityName) }).catch((err) => console.log(err))
Another way is to use async-await API interface which is supported in node 8.
async function getCityCode(latLongCityCodeURL){ const result = await http.get(latLongCityCodeURL, (resp) => { resp.on("data", (chunk) => { var result = JSON.parse(chunk); var cityCode = result.Key; var cityName = result.EnglishName; return {cityCode, cityName}; }); }).on("error", (err) => { return err; console.log("Error: " + err.message); }); return result; } getCityCode(latLongCityCodeURL) .then((res) => { console.log(res.cityCode, res.cityName) })