Wait for response from request before returning
Andrew Mclaughlin
I am trying to create a function with a GET request that returns a portion of the data from the GET request. However, it keeps returning before the data is retrieved, so I keep getting "undefined". How can I set this up so it actually waits for the data to be set before returning?
let getInfo = async () => { const request = net.request({ url: URL }) return new Promise((resolve, reject) => { // Promise being here DOES work request.on('response', (response) => { response.on('data', (chunk) => { //return new Promise((resolve, reject) => { //Promise being here does NOT work let body = JSON.parse(chunk) let info = body.data if (info){ resolve(info); } reject(); //}) }); }); request.write('') request.end() }).then(data => { console.log("From then: "+data) return data })
}
getInfo().then(data => { console.log("From outside: "+data)
})Edit: This is the updated version that still does not work. I am trying to use the native electron method and I don't see why this doesn't work. The "From then:" part displays the info correctly. But when run "From outside:" it prints undefined. Does the issue have anything to do with the response.on being nested inside the request.on?
Solution: As @NidhinDavid showed in his answer, the issue was that the promise was inside the 'response' listener. Moving the 'GET' request from start to finish inside the Promise fixed it to giving the correct output. I have updated my code to reflect that for future individuals.
3 Answers
let getInfo = () => { let info; const request = net.request({ url: URL }) return new Promise((resolve, reject) => { request.on('response', (response) => { response.on('data', (chunk) => { request.write('') request.end() let body = JSON.parse(chunk) info = body.data if (info) { resolve(info) } else { reject('Something went wrong'); } }); }); })
}
getInfo() .then(data => { // this will be your info object console.log(data) }) .catch(err => { // this will log 'Something went wrong' in case of any error console.log(err) })You need to return inside your, on type event handler. Read more about asynchronous code and synchronous code here
I couldn't find the net module and the one which is included with Nodejs do not have request method. So to get the similar concept of event emiters and promise I am using http module and doing a http request to fetch json and parse it
'use strict'
var https = require('https');
const getInfo = async () => { // create a new promise chain // remember it is a chain, if one return is omitted // then the chain is broken return new Promise((resolve, reject) => { var options = { host: 'support.oneskyapp.com', path: '/hc/en-us/article_attachments/202761727/example_2.json' }; // start the request https.request(options, function (response) { var str = ''; // data arrives in chunks // chunks needs to be stitched together before parsing response.on('data', function (chunk) { str += chunk; }); // response body obtained // resolve (aka return) the result // or parse it, or do whatever you want with it response.on('end', function () { resolve(str) }); // errors are another event // listen for errors and reject when they are encountered response.on('error', function (err) { reject(err) }) }).end() })
}
//*********************************************
// using async await
//*********************************************
// if this is the entry point into app
// then top-level async approach required
(async ()=>{ try{ let data = await getInfo() console.log("From ASYNC AWAIT ") console.log(JSON.stringify(JSON.parse(data))) } catch (err) { console.log("operation failed, error: ", err) }
})();
//************************************************
// using promise chains
//************************************************
getInfo()
.then((data)=>{ console.log("FROM PROMISE CHAIN ") console.log(JSON.stringify(JSON.parse(data)))
})
.catch((err)=>{ console.log("operation failed, error: ", err)
}) 1 Tyr this, it might works for you,
let info;
const getInfo = async (_url)=>{
const response = await fetch(_url);
const data = await response.json();
info = data;
} ;
const url = "some url";
getInfo(url);
console.log(info);Async function always returns a promise, so either consume that promise or internally await the data and assign it to some variable. Check for the valid data required in info by logging it to the console.
1