Node JS callback executed without waiting - node.js

I have the following function which performs a GET call. I want to wait for the response and then perform the next step. My code looks like this
getListOfChannels : function(token, callback){
var Channels = [];
var options = { method: 'GET',
url: url,
headers:
{
'x-api-key': token } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
var json = JSON.parse(body)
var data = json.MemberEntitlement;
for(var i=0 ; i < data.length ; i++){
if(data[i].Entitled == false){
Channels.push(data[i].ChannelNumber);
}
}
});
callback(Channels[0]);
}
Also my callback function is just printing the value
simplePrint : function(arg){
console.log(arg)
}
But still, the callback function does not wait for the full response and prints out undefined.
What should i do. I can add implicit wait but that doesnt seem like a good practice.

I think you are invoking callback after the request function invocation. It's not in request's scope, but in getListOfChannels scope. Therefore, callback is running synchronously. Try replacing:
});
callback(Channels[0]);
}
with
callback(Channels[0]);
});
}

Related

How to Store an respone into a variable nodejs request module

I am trying to store the response of an http request made using nodejs by request module but the problem is I can't acsess it after the request is completed in more details we can say after the callback
How I can add it
Here is what I tried till now
Tried to use var instead of let
Tried passing it to a function so that i can use it later but no luck
Here is my code can anyone help actually new to nodejs that's why maybe a noob question
var request = require('request')
var response
function sort(body) {
for (var i = 0; i < body.length; i++) {
body[i] = body[i].replace("\r", "");
}
response = body
return response
}
request.get(
"https://api.proxyscrape.com/?request=getproxies&proxytype=http&timeout=10000&country=all&ssl=all&anonymity=all",
(err, res, body) => {
if (err) {
return console.log(err);
}
body = body.split("\n");
sort(body);
}
);
console.log(response)
In this I am fetching up the proxies from this api and trying to store them in a variable called as response
var request = require("request");
var response;
async function sort(body) {
await body.split("\n");
response = await body;
console.log(response); // this console log show you after function process is done.
return response;
}
request.get(
"https://api.proxyscrape.com/?request=getproxies&proxytype=http&timeout=10000&country=all&ssl=all&anonymity=all",
(err, res, body) => {
if (err) {
return console.log(err);
}
sort(body);
}
);
// console.log(response); //This console log runs before the function still on process, so that's why it gives you undefined.
Try this code it works fine I just tested.
put the console log inside the function so you can see the result.
The console.log that you put actually runs before you process the data so that's why you are getting "undefined".
Actually, you will get the data after the sort Function is done processing.

How to make Node.js wait on a function call containing a post request?

I am new to Node.js and I cannot make the code wait to finish my call to askKB, which contains an http request.
I need askKB to finish first so that I can use the variable speechText but the the code after the function call runs before I get speechText back.
I also tried to play around with await/async but was not successful.
handle(handlerInput) {
var newQuestion = handlerInput.requestEnvelope.request.intent.slots.phrase.value;
const speechText = askKB(newQuestion);// <-- I want this function finish first because I need the variable speechText
return handlerInput.responseBuilder
.speak(speechText)
.withSimpleCard('Balance', speechText)
.getResponse();
},
Here is the askKB function:
function askKB(question){
var answer;
var requestOptions = {
url: host + route,
headers: {
//some code here
},
method: "POST",
json: true,
json: { "question": question }
};
request(requestOptions, function(err, response, body) {
if (!err && response.statusCode == 200) {
answer = body.answers[0].answer;
}
else {
answer = "Sorry! something went wrong. Try again...";
}
});
return answer;
}
I would appreciate any help :)
You can use async - await functions, and of course, promises.
A Promise is a proxy for a value not necessarily known when the promise is created. It allows you to associate handlers with an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future.
A Promise is in one of these states:
pending: initial state, neither fulfilled nor rejected.
fulfilled: meaning that the operation completed successfully.
rejected: meaning that the operation failed.
So this will give you the needed time before returning data.
If you don't want promises, you can still make your code work with asynchronous functions.
async function askKB(question){
var answer;
var requestOptions = {
url: host + route,
headers: {
//some code here
},
method: "POST",
json: true,
json: { "question": question }
};
await(request(requestOptions, function(err, response, body) {
if (!err && response.statusCode == 200) {
answer = body.answers[0].answer;
}
else {
answer = "Sorry! something went wrong. Try again...";
}
}));
return answer;
}

node.js server and AWS asynchronous call issue

I have a simple node Express app that has a service that makesa call to a node server. The node server makes a call to an AWS web service. The AWS simply lists any S3 buckets it's found and is an asynchronous call. The problem is I don't seem to be able to get the server code to "wait" for the AWS call to return with the JSON data and the function returns undefined.
I've read many, many articles on the web about this including promises, wait-for's etc. but I think I'm not understanding the way these work fully!
This is my first exposer to node and I would be grateful if somebody could point me in the right direction?
Here's some snippets of my code...apologies if it's a bit rough but I've chopped and changed things many times over!
Node Express;
var Httpreq = new XMLHttpRequest(); // a new request
Httpreq.open("GET","http://localhost:3000/listbuckets",false);
Httpreq.send(null);
console.log(Httpreq.responseText);
return Httpreq.responseText;
Node Server
app.get('/listbuckets', function (req, res) {
var bucketData = MyFunction(res,req);
console.log("bucketData: " + bucketData);
});
function MyFunction(res, req) {
var mydata;
var params = {};
res.send('Here are some more buckets!');
var request = s3.listBuckets();
// register a callback event handler
request.on('success', function(response) {
// log the successful data response
console.log(response.data);
mydata = response.data;
});
// send the request
request.
on('success', function(response) {
console.log("Success!");
}).
on('error', function(response) {
console.log("Error!");
}).
on('complete', function() {
console.log("Always!");
}).
send();
return mydata;
}
Use the latest Fetch API (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to make HTTP calls. It has built-in support with Promise.
fetch('http://localhost:3000/listbuckets').then(response => {
// do something with the response here
}).catch(error => {
// Error :(
})
I eventually got this working with;
const request = require('request');
request(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
parseString(body, function (err, result) {
console.log(JSON.stringify(result));
});
// from within the callback, write data to response, essentially returning it.
res.send(body);
}
else {
// console.log(JSON.stringify(response));
}
})

Nodejs Ajax Call

I was calling this function from javascript file. which was working perfect but now i want to call same function using Node js. please give me any alternate method. this function is use to insert data onclick event before.
function signup_validations_google(name_g,email_g,pass_g)
{
xmlhttp = new XMLHttpRequest();
xmlhttp.open("GET","http://localhost:8000/uri?name="+name+"&email="+email+"&pass="+pass, true);
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
string=xmlhttp.responseText;
alert("Registration successful");
}
}
xmlhttp.send();
}
In node.js, you would generally use http.get() from the http module or request() from the request module. I find request() is a bit easier to use:
const request = require('request');
let query = {name, email, pass};
request({uri: "http://localhost:8000/uri", query: query}, function(err, msg, body) {
if (err) {
// error here
} else {
// response here
}
});
There are a zillion other possible options for the request() module described here.

Node.js function returns undefined

I probably have some issues with the asyncness of Node.js.
rest.js
var Shred = require("shred");
var shred = new Shred();
module.exports = {
Request: function (ressource,datacont) {
var req = shred.get({
url: 'ip'+ressource,
headers: {
Accept: 'application/json',
},
on: {
// You can use response codes as events
200: function(response) {
// Shred will automatically JSON-decode response bodies that have a
// JSON Content-Type
if (datacont === undefined){
return response.content.data;
//console.log(response.content.data);
}
else return response.content.data[datacont];
},
// Any other response means something's wrong
response: function(response) {
return "Oh no!";
}
}
});
}
}
other.js
var rest = require('./rest.js');
console.log(rest.Request('/system'));
The problem ist if I call the request from the other.js I always get 'undefined'. If I uncomment the console.log in rest.js then the right response of the http request is written to the console. I think the problem is that the value is returned before the actual response of the request is there. Does anyone know how to fix that?
Best,
dom
First off, it is useful to strip down the code you have.
Request: function (ressource, datacont) {
var req = shred.get({
// ...
on: {
// ...
}
});
}
Your Request function never returns anything at all, so when you call it and console.log the result, it will always print undefined. Your request handlers for the various status codes call return, but those returns are inside of the individual handler functions, not inside Request.
You are correct about the asynchronous nature of Node though. It is impossible for you to return the result of the request, because the request will still be in progress when your function returns. Basically when you run Request, you are starting the request, but it can finish at any time in the future. The way this is handled in JavaScript is with callback functions.
Request: function (ressource, datacont, callback) {
var req = shred.get({
// ...
on: {
200: function(response){
callback(null, response);
},
response: function(response){
callback(response, null);
}
}
});
}
// Called like this:
var rest = require('./rest.js');
rest.Request('/system', undefined, function(err, data){
console.log(err, data);
})
You pass a third argument to Request which is a function to call when the request has finished. The standard Node format for callbacks that can fail is function(err, data){ so in this case on success you pass null because there is no error, and you pass the response as the data. If there is any status code, then you can consider it an error or whatever you want.

Resources