Using await for request and 'if' implementation - node.js

I see the below code in my application. I am not able to understand the logic implemented.
Can someone explain me how the below works. Is this a different implementation of 'if' condition.
Also, Can I put 'await' ahead of 'request' in the below code since I need to wait till I get response for this request made. If not, how else can I use await below.
newstatus != undefined &&
request(params, (error, response, body) => {
error && console.info("error");
console.info("response received:", body);
});

In javascript this && operator named as AND
&& means if a condition returns true then move to the next step otherwise not go for the next inner step.
newstatus != undefined &&
request(params, (error, response, body) => {
error && console.info("error");
console.info("response received:", body);
});
the above example demonstrates that if(newstatus != undefined) condition true then call request API call.
To answer your second question how can we use async in it.
await use for promises only or before functions that return promise after completing some tasks like API call.
you have to make a function for request API that return Promise
here we have created the doRequest() function that will return a promise.
solution:
function doRequest(url) {
return new Promise(function (resolve, reject) {
request(params, (error, response, body) => {
if (!error && res.statusCode == 200) {
resolve(body);
} else {
reject(error);
}
});
});
}
// Usage:
async function main() {
let res = await doRequest(url);
console.log(res);
}
OR
newstatus != undefined && await doRequest(url);

Related

Unable to save async operation result in an array

I am calling network requests in a forEach loop, each request returns a new object which I would like to push to an array that is outside the forEach. When it is called after awaiting for the network requests to complete, it returns as empty "[]".
return this.get(urlOne, function (error, response) {
if (response.statusCode === 200) {
let array = [];
stores.forEach((store) => {
this.get(urlTwo, function (error, response) {
if (response.statusCode === 200) {
array.push(response.body);
}
});
});
console.log(array);
}
});
This is just a guess but, stores.forEach contents are async thus console.log(array) is called right after stores.forEach() is calle d(not completed) meaning array is blank.
console.log(array); probably needs to be called when the requests are actually done not right after they are made.
Simplest way to test if this is true is to see the array for every push if you see the array growing with your data there is the problem.
return this.get(urlOne, function (error, response) {
if (response.statusCode === 200) {
let array = [];
stores.forEach((store) => {
this.get(urlTwo, function (error, response) {
if (response.statusCode === 200) {
array.push(response.body);
console.log(array);
}
});
});
}
});
(EDIT)
if (response.statusCode === 200)
array.push(response.body);
else if(response.statusCode === 204)
console.log(array);
Status code 204 means No Content, if this isn't being sent automatically or an equivalent, you may need to send it manual some how.

node.js return function value inside setinterval

I was called function inside setinterval. But i don't take return value from function.
My code:
function getApiData() {
request({
url : 'http://testest.com',
json : true
}, (error, response , body) => {
if(!error && response.statusCode == 200){
return JSON.stringify(body);
}
else{
return undefined;
}
});
}
Call:
setInterval(() => {
var data = getApiData();
console.log(data);
}, 2000);
Output : Undefined
Please help me. (I am learning new)
As #Aravindan Ve pointed out, there is no way to get retrieve the value returned by that function.So, define a different function
functionPrintResponse(res){
console.log(res)
}
and instead of returning there, invoke functionPrintResponse(JSON.stringify(body))

Nodejs Executing Functions

Im new to Nodejs and was wondering why the functions execute out of order instead of how ive written it:
var tor_proxy = require("tor-request")
var s = require("sleep");
tor_proxy.setTorAddress("localhost", 9050);
tor_proxy.TorControlPort.password = "password";
function ShowIP() {
tor_proxy.request("http://ident.me", function(err, response, body) {
if(!err && response.statusCode == 200) {
console.log(body);
}
});
}
function Renew() {
tor_proxy.renewTorSession(function() { console.log("renewed"); });
}
ShowIP();
Renew();
ShowIP();
//Id Like It To Show The IP Then Renew Then Show The New IP
//But Instead It's Out Of Order
Nodejs is event driven (correct me if im wrong) and any help will be appreciated. Thanks :)
The script will be executed like this:
Inside ShowIP(), tor_proxy.request() sends a request to http://ident.me .
Without waiting for any reply from http://ident.me, function Renew() is executed.
tor_proxy.renewTorSession() is likely to be an asynchronous function. If so, after it begins, the next ShowIP() will be executed without waiting for renewTorSession() to complete.
Depending on how fast http://ident.me replies and how fast renewTorSession() completes, the results may vary.
To execute these functions in proper order, you can search for the following keywords:
Promise
Async/Await
util.promisify() from Node.js
Libraries like Async.js
An example using promise, async and await:
var tor_proxy = require('tor-request');
tor_proxy.setTorAddress('localhost', 9050);
tor_proxy.TorControlPort.password = 'password';
function ShowIP() {
return new Promise((resolve, reject) => {
tor_proxy.request('http://ident.me', function (err, response, body) {
if (err) reject(err);
else if (response.statusCode !== 200) reject('response.statusCode: ' + response.statusCode);
else {
console.log(body);
resolve();
}
});
});
}
function Renew() {
return new Promise((resolve, reject) => {
tor_proxy.renewTorSession(() => {
console.log('renewed');
resolve();
});
});
}
async function testFunction() {
// Await makes sure the returned promise completes before proceeding.
// Note that await keyword can only be used inside async function.
try {
await ShowIP();
await Renew();
await ShowIP();
console.log('done!');
} catch (error) {
console.log(error);
}
}
testFunction();

ES7 - how can I replace Promise with await?

One thing puts me off with Promise is that it is difficult to grasp with resolve and reject. Also the need of wrapping for Promise is ugly. Unless you use it very often, I tend to forget how to use them over time. Besides, code with Promise is still messy and hard to read. Hence I don't really like using it at all - because it has not much different from the callback hell. So I thought with ES7 await, I can avoid using Promise and giving me some more faith in JavaScript, but it seems that it is not the case. For instance:
const getOne = async () => {
return Weather.findOne(options, function(err, weather) {
//
});
}
const getWeather = async () => {
const exist = await getOne();
if (exist == null) {
return new Promise(function(resolve, reject) {
// Use request library.
request(pullUrl, function (error, response, body) {
if (!error && response.statusCode == 200) {
// Resolve with the data.
resolve(body);
} else {
// Reject with the error.
reject(error);
}
});
});
}
}
const insertWeather = async () => {
try {
const data = await getWeather();
} catch (err) {
res.set('Content-Type', 'application/json');
return res.status(200).send('Error occurs: ' + err);
}
}
insertWeather();
request(pullUrl, function (error, response, body) {} is an AJAX call from request package for nodejs.
I have to wrap it with Promise - but not precede it with await. Ideally this is what I imagine:
return await request(pullUrl, function (error, response, body) {...}
But if I do that, I will get the request object in return, instead of the data return from the request package - at this line:
const data = await getWeather();
Any ideas or solutions to avoid using Promise in the case such as the one above?
You'll find bluebird and node.js now come with promisify to allow you to consume Node callbacks as promises when you need too. Alternatively, you can consider a functional reactive approach and use a library like RxJS which will handle promises, node callbacks and other data types into streams.
const promisify = require('utils').promisify // alternatively use bluebird
const request = require('request-promise');
const weatherFn = promisify(Weather.findOne);
const weatherOptions = {};
async function getWeatherIfDoesNotExist() {
try {
const records = await weatherFn(weatherOptions);
if (records === null) {
return await request('/pullUrl');
}
} catch(err) {
throw new Error('Could not get weather');
}
}
async function weatherController(req, res) {
try {
const data = await getWeatherIfDoesNotExist();
} catch (err) {
res.set('Content-Type', 'application/json');
return res.status(200).send('Error occurs: ' + err);
}
}
function altWeatherController(req, res) {
return getWeatherIfDoesNotExist()
.then((data) => { // do something })
.catch((err) => {
res.set('Content-Type', 'application/json');
return res.status(200).send('Error occurs: ' + err);
})
}
As mentionned in the documentation here, you will need to wrap request with interfaces wrappers like request-promise (or you can find alternatives interface in the documentation) in order to return a Promise from request.

Passing data from request module out of a function? [duplicate]

This question already has answers here:
NodeJS get async return value (callback) [duplicate]
(2 answers)
Closed 5 years ago.
I'm working on a module that returns a the data retrieved from an http request using the request module. However, I'm having a problem when I want to pass the data out of the function. Take this, for example.
function getData(term) {
var parsedData
request.post(url, term, (err, response, body) => {
if (!err && response.statusCode == 200) {
parsedData = doSomethingTo(body);
}
});
return parsedData;
}
This method doesn't work, since the function getData() performs asynchronously and the value is returned before the request can actually return the proper data.
function getData(term) {
var parsedData
request.post(url, term, (err, response, body) => {
if (!err && response.statusCode == 200) {
parsedData = doSomethingTo(body);
return parsedData;
}
});
}
This method doesn't work either, as it will merely make the request function return the parsed data, and not the getData function.
How could I make the parent function return the data parsed from the request function?
use Promise like this :
function getData(term) {
return new Promise(function(resolve){
request.post(url, term, (err, response, body) => {
if (!err && response.statusCode == 200) {
var parsedData = doSomethingTo(body);
resolve(parsedData);
}
});
});
}
and you can call your function like this :
getData(term).then(function(data){
//console.log(data);
})
use the bluebird promise module very fast.
var Promise = require('bluebird');
function getData(term) {
return new Promise(function(resolve,reject){
if (!err && response.statusCode == 200) {
var parsedData = doSomethingTo(body);
resolve(parsedData);
}else{
reject(err);
}
});
};
then the place you are calling the function do this;
var promise = getData(term);
promise.then(function(data){console.log(data)}).catch(function(err){console.error(err)});

Resources