Variable getting undefined outside the function [duplicate] - javascript

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed 4 months ago.
I am trying to use the data from one api in another so i need to use the variable in another function call but it is getting undefined even after i've initialized it globally.
var latitude,longitude;
var cityn=req.body.cityname;
const appid="..."
var unit="metric"
const url1="https://api.openweathermap.org/geo/1.0/direct?q="+cityn+"&limit=5&appid="+appid
https.get(url1,function(response){
response.on("data",function(da){
const CityDetails=JSON.parse(da);
latitude=CityDetails[0].lat;
longitude=CityDetails[0].lon;
console.log(latitude) //--> defined
console.log(longitude) //--> defined
})
})
console.log(latitude) //--> undefined
console.log(longitude) //--> undefined
const url2="https://api.openweathermap.org/data/2.5/weather? lat="+latitude+"&lon="+longitude+"&appid="+appid+"&units="+unit;
I tried initializing it globally and also without using 'var' 'const' but both of the ways are not working.

This is because you want to log the lat-long data before it arrives from the server. You need to await the call before doing so or use synchronous HTTP request.
Better to use async-await for this kind of stuff. You can wrap the node.js HTTPS lib with this code:
function doRequest(options, data) {
return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
res.setEncoding('utf8');
let responseBody = '';
res.on('data', (chunk) => {
responseBody += chunk;
});
res.on('end', () => {
resolve(JSON.parse(responseBody));
});
});
req.on('error', (err) => {
reject(err);
});
req.write(data)
req.end();
});
}
https://stackoverflow.com/a/56122489/607033
You can use it this way:
var latitude,longitude;
var cityn=req.body.cityname;
const appid="..."
var unit="metric"
(async function (){
const options = {
hostname: 'api.openweathermap.org',
port: 443,
path: "/geo/1.0/direct?q="+cityn+"&limit=5&appid="+appid,
method: 'GET'
};
var CityDetails = await(doRequest(options));
latitude=CityDetails[0].lat;
longitude=CityDetails[0].lon;
console.log(latitude);
console.log(longitude);
const options2 = {
hostname: 'api.openweathermap.org',
port: 443,
path: "data/2.5/weather? lat="+latitude+"&lon="+longitude+"&appid="+appid+"&units="+unit,
method: 'GET'
};
var data2 = await(doRequest(options2));
})();

Related

axios data is undefined [duplicate]

This question already has answers here:
Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference
(7 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed 9 months ago.
I'm trying to perform an axios get request.
axios
.get("http://10.10.0.145/api/session", {
headers: {
'Cookie' : user_cookie
}
},
)
.then(res => {
result = res.data;
id_user_intervention = res.data.id;
console.log(id_user_intervention); //IS NOT UNDEFINED
})
.catch(error => {
console.error(error)
})
console.log(id_user_intervention); //IS UNDEFINED
I need to use id_user_intervention outside the axios request. I assign res.data.id to id_user_intervention, but this variable is undefined outside the axios request...how can I solve this problem?
First of all, it's better you learn async/await on javascript. Then, try the following solution:-
const testFunction = async () => {
let id_user_intervention = null;
try {
const response = await axios.get("http://10.10.0.145/api/session", {
headers: {
'Cookie': user_cookie
}
})
id_user_intervention = response.data.id;
} catch (err) {
console.error(err);
}
return id_user_intervention;
}
const anotherFunction = async () => {
const data = await testFunction();
console.log(data);
}
Hope it will work properly.

Issue regarding async functions - await is only valid in async functions [duplicate]

This question already has answers here:
await is only valid in async function
(14 answers)
How do I return the response from an asynchronous call?
(41 answers)
Closed 1 year ago.
In a file called getData.js , I wrote the following code
module.exports = async function (page, id) {
const options = {
...
};
axios
.request(options)
.then((response) => {
myData = JSON.stringify(response.data);
return myData;
})
.catch((error) => {
console.error(error);
});
};
Now in my main index.js file, I imported the above module then I have this snippet,
const server = http.createServer((req, res) => {
res.writeHead(200, { "Content-Type": "application/json" });
let finalData = await getData(myPage, myID);
res.end(finalData);
});
When I run this node crashes and I get this error
SyntaxError: await is only valid in async functions and the top level bodies of modules
How do I make my code to work? I thought of using async-await becuase response.data is very big, but clearly I don't understand async-await functions fully. In the external module, If I try to return myData outside the .then block and also don't use async-await, then I get undefined finalData.

why the async function doesn't return values? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 2 years ago.
I have a node.js app with websocket
When the user get into '/' I need to send command message (json message) with web socket to other application.
When I get results from the other application, I need to return it.
It seems that I return empty results to the user, and I don't know why
serv.js file:
const websocket = require('ws')
async function sendData(command) {
const ws = new websocket('ws://127.0.0.1:5678')
ws.on('open', function open() {
ws.send(JSON.stringfuly(command))
});
ws.on('message', function incoming(data) {
return data
});
return {}
}
module.exports = {
sendData,
}
index.js file:
connection = require('serv');
const router = Router();
.route('/')
.get(async(req, rep) => {
// fill json command
command = fillCommand()
result = await connection.sendData(command)
res.json(result);
})
I tried to debug, and I can see that results = await connection.sendData(command) get {} result only.
I tried to remove the return {} and I got the same results
I see that I'm getting results from the ws.on('message'... , But it is not get back to index.js
what am I missing and how can I fix it ?
I believe the problem is that you are returning the data inside the listener for the message event, which doesn't return the value from the async function. This kind of conversion from callbacks to promises can only be done with the Promise constructor.
function sendData(command) {
const ws = new websocket("ws://127.0.0.1:5678");
ws.on("open", function open() {
ws.send(JSON.stringfuly(command));
});
return new Promise( (res, rej) => {
ws.on("message", (data) => {
res(data);
});
// Don't forget to handle errors.
ws.on("error", (error) => {
rej(error);
});
});
}

Why doesn't my "required" function return anything? [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
So i have this little Express.js Application, which accepts a POST-request with a "city" as body. The application processes the call and uses an external service for that. I tried to split up the "Pure" logic from the REST-controller to keep it clean, but somehow when i call the "weather" method, it won't return anything, even if the String, i am passing, is a valid object.
My guess is, that there is an issue with an asynchronious call, but i don't see myself in the position, to solve it myself.
RestController.js
module.exports = (function() {
var router = require('express').Router()
var bodyParser = require('body-parser')
var weather = require('./weather')
router.use(bodyParser.urlencoded({ extended: true }))
router.use(bodyParser.json())
//TODO DATABASE CONNECTION
//REST CONTROLLER
router.get('/', function(req, res) {
res.json({response: 'Hello world!'})
})
router.post('/weather', function(req, res) {
var r = weather(req.body.city)
res.send(r)
})
return router
})();
weather.js
var request = require('request')
module.exports = function(loc) {
request('http://api.openweathermap.org/data/2.5/weather?q='+loc+'&units=metric&APPID=API_TOKEN', function(err , ires) {
if(!err) {
json = JSON.stringify({temp: JSON.parse(ires.body).main.temp, name: JSON.parse(ires.body).name})
console.log(json)
return json
}
else {
return err
}
})
};
Best regards,
Tim
You should pass a callback to your weather function so you can handle it when it's complete. e.g.
module.exports = function(loc, callback) {
request('http://api.openweathermap.org/data/2.5/weather?q='+loc+'&units=metric&APPID=API_TOKEN', function(err , ires) {
if(!err) {
json = JSON.stringify({temp: JSON.parse(ires.body).main.temp, name: JSON.parse(ires.body).name})
console.log(json)
callback(null, json)
} else {
callback(err)
}
})
};
Then use as follows in your program:
router.post('/weather', function(req, res) {
var r = weather(req.body.city, function (e, result) {
if (e) return res.status(500).send({error: e});
res.send(result)
})
})
This is the standard node pattern (there are better ones). Node is non-blocking so it will not wait for your weather request to complete. It will eventually handle it on the event loop once the callback is finally invoked.

Sync http request in Node [duplicate]

This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 7 years ago.
I'm new to node and I'm trying to figure out the callbacks and the async nature of it.
I have this kind of function:
myObj.exampleMethod = function(req, query, profile, next) {
// sequential instructions
var greetings = "hello";
var profile = {};
var options = {
headers: {
'Content-Type': 'application/json',
},
host: 'api.github.com',
path: '/user/profile'
json: true
};
// async block
https.get(options, function(res) {
res.on('data', function(d) {
// just an example
profile.emails = [
{value: d[0].email }
];
});
}).on('error', function(e) {
console.error(e);
});
//sync operations that needs the result of the https call above
profile['who'] = "that's me"
// I should't save the profile until the async block is done
save(profile);
}
I was also trying to understand how to work with the Async library given that most of the node developers use this or a similar solution.
How can I "block" (or wait for the result) the flow of my script until I get the result from the http request? Possibly using the async library as an example
Thanks
Based on the fact that you're trying to "block" your script execution, I don't think you have a firm grasp on how async works. You should definitely read the dupe I suggested, especially this response:
How do I return the response from an asynchronous call?
To answer your question more specifically:
async.waterfall([
function(callback) {
// async block
https.get(options, function(res) {
res.on('data', function(d) {
// just an example
profile.emails = [
{value: d[0].email }
];
callback(null);
});
}).on('error', function(e) {
throw e;
});
},
function(callback) {
// I should't save the profile until the async block is done
save(profile);
callback(null);
}
]);

Categories