Your "problem" consists of the fact that this request made by the module is asynchronous i.e.: the request will be made and subsequently you will get a reply, either the body of the request or an error that occurred in the request.
You are declaring a variable without a content (response
) hoping to assign a value to it when the answer comes though, is accessing (using) this variable before it happens (console.log
) ... will always be undefined
You must use a callback to work on this value, example:
const request = require("request");
function getWeather(callback) {
request(url, function (error, response, body) {
callback(body)
})
}
getWeather(function(responseBody) {
console.log(responseBody)
})
By default this module does not work with Promise()
but as described by the module itself you can use the adjacent packages if you want to work on "Promises" see links of adjacent packages:
https://www.npmjs.com/package/request#Promises-asyncawait
If you don’t want to use extra packages know that you can do this natively using the native module utils and "promising" the request:
const util = require('util')
const request = require("request");
const requestPromise = util.promisify(request);
function getWeather(url) {
return requestPromise(url).then(response => {
if ( response.statusCode === 200 ) {
return response.body
}
return Promise.reject(response.statusCode)
})
}
getWeather('https://www.google.com').then(body => {
console.log(body)
}).catch(e => console.log(e))
Since not all possible status codes are an error in the request you should treat them as you really want them, the above example will only return the body of the request if the status is equal to 200 and reject all others.
Promise()
by nature are "asynchronous" functions but you can use await to work on a "synchronous" behavior as long as it is within a function async:
const util = require('util')
const request = require("request");
const requestPromise = util.promisify(request);
async function done() {
let response = await requestPromise('https://www.google.com')
console.log(response.body)
}
done()
In the above example there is no guarantee that the answer will have a property "body" and cannot do any treatment in case of error/failure other than that all the code will "wait" for the order to complete and a server may take too long to respond.
A "better" approach would be to address possible gaps in the request in a block .catch()
:
const util = require('util')
const request = require("request");
const requestPromise = util.promisify(request);
async function done() {
async function getWeather(url) {
return requestPromise(url).then(response => {
if ( response.statusCode === 200 ) {
return response.body
}
return Promise.reject(response.statusCode)
}).catch(err => {
return err
})
}
console.log(await getWeather('https://www.google.com'))
}
done()
reading:
Mozilla Docs: async/await
You must put the
console.log
inside the callback. It is not recommended to try to remove a variable from within the scope of a callback call. You can better understand in that reply.– Luiz Felipe