Pulling a value from Asynchronus Function - node.js

I'm working with we sockets and I have a lot of requests, so I figured it'd be best to pull the data out of the asynchronus funtion and put it in a variable outside of it. My code looks like this but I just get request [Pending]:
var variable;
var Request = require("request");
function getAsyncValue() {
return new Promise((resolve, reject) => {
Request.get(url, (error, response, body) => {
if(error) {
return reject(err);
}
var object = JSON.parse(body);
var value = object.data.available_balance;
resolve(value);
});
});
}
async function asyncWrapper() {
variable = await getAsyncValue();
return(variable);
}
printVariable = asyncWrapper();
console.log(printVariable);
Any idea on how I can achieve my goal?

Your asyncWrapper is a promise. You have to use await.
To use an await, you need an async function. So you can use a IIFE(Immediately Invoked Functions Expressions) async function.
async function(){
printVariable = await asyncWrapper();
console.log(printVariable);
}();

This was what I was looking for:
var request = require('sync-request');
var returnCode;
var getUrl = "url";
returnCode = httpGet(getUrl);
var object = JSON.parse(returnCode);
var balance = objekt.data.available_balance;
console.log(balance);
function httpGet(url){
var response = request(
'GET',
url
);
return response.body;
}

put your console.log inside the asyncWrapper() as following:
async function asyncWrapper() {
variable = await getAsyncValue();
console.log(printVariable);
return(variable);
}
printVariable = asyncWrapper();
the reason for doing this is because when u had console.log() after the asyncWrapper(), it will be called immediately and not in an sync manner as u would need.
or you can do the following:
Just wrap the asyncWrapper function call inside an another async method and await for the result of asynWrapper() in that. Look below:
var function1 = async function () {
printVariable = await asyncWrapper();
console.log(printVariable);
}

Related

How to call a function that waits for return of API call (Node.js)

While learning Node.js and after some trial and error I have this working code that makes API calls to retrieve user records where each API call is dependent on the result of the previous API call.
const axios = require('axios')
var getDataById = async (config) => {
var response = await axios(config);
var userById = {};
userById['userId'] = response.data["userId"];
return(userById);
};
(async () => {
var a = []; // array for storing user data
var userId = '0001';
var done = false; // false until user '0010' is reached
while (!done) {
url = "https://someurl.com/" + userId;
var axiosconfig = {
method: 'get',
url: url,
headers: {
'Authorization': 'Bearer SECRET_TOKEN'
}
};
var userDataById = await getDataById(axiosconfig);
a.push(userDataById);
userId = userDataById['userId'];
if (userId == '0010') { done = true }
}
})()
How can I call this code from elsewhere in my program in such a way that
I can pass arguments to it...for example 'userId'
I can return 'a' to the calling function
the calling function waits for 'a' to be returned before continuing
TBH, I don't quite get how this works.
;(async () => {})()
Is there a better way of coding this?
You need to create an async function and then await it.
The function definition will look like this
async function AddUser(userId)
You can return any variable and you call it like this:
await addUser('002')
await keyword make sure that the calling function waits for 'a' to be returned before continuing.
For your last question:
(async () => {})()
Is an arrow function.
See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions
Using async keyword + arrow function is a trick to allow you to create an async context and being able to use await. The two last () are used to direct call this function.

Awaiting coordinates from geocoding google maps API returns pending promise

I am trying to return coordinates of given adress with gooogle maps geocoding API and fetch. I am able to log these coordinates inside my get fuction, but I have no idea how to return them from the function to use it somewhere else in the code. Already tried multiple varaitions of two approaches:
function getCoordinates1(name) {
locObj = fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${name}&key=mykey`).then( (res) => res.json()).then( (data) =>
{
console.log(data.results[0].geometry.location);
return data.results[0].geometry.location;
}).then((res) => res);
}
let coordinates1 = getCoordinates1(latinaze(name2));
console.log(coordinates1);
async function getCoordinates2(name) {
locObj = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${name}&key=mykeyk`).then( (res) => res.json()).then( (data) =>
{
console.log(data.results[0].geometry.location);
//return data.results[0].geometry.location;
}).then((res) => res);
return locObj
}
let coordinates2 = await getCoordinates2(latinaze(name2));
console.log(coordinates2);
First function returns undefined, second returns pending promise. What am I doing wrong?
The first function returns undefined because you don't return anything. As simple as that ;)
The second function returns a pending promise because you don't wait for the promise to be resolved. The promise gets resolved when the callback inside then is invoked, but that happens after you return locObj in getCoordinates2.
You should try this:
// function definition
async function getCoordinates3(name) {
const resp = await fetch(`https://maps.googleapis.com/maps/api/geocode/json?address=${name}&key=mykeyk`)
const data = await resp.json();
return data.results[0].geometry.location;
}
// usage
const coordinates3 = await getCoordinates3(latinaze(name3));
I couldn't return any value from function, so I made it a class method and set a property in function body. Now I can get the value form that property after I call the function:
export default class SearchModel {
constructor() {
this.start = '';
this.meta = '';
this.coors = [];
this.address = 'none';
}
//translate coordinates to address
async getAdress(coordinates) {
try {
let geocodeCoordinates = `https://maps.googleapis.com/maps/api/geocode/json?latlng=${this.coors[0]},${this.coors[1]}&key=${process.env.API_GM_KEY}`
const rawData = await fetch(geocodeCoordinates);
//console.log(await rawData.json());
return await rawData.json();
} catch (error) {
return new Error(`Wild ERROR occured, can't get LocObj. Details: ${error}`);
} }
async displayAdress(coordinates) {
const data = await this.getAdress(coordinates);
const dataAdress = await data.results[0].formatted_address;
this.address = await dataAdress; }
}

Node.js Await Async with util class function

I am fairly new to Node.js and I am trying to pick it up with Koa.js framework.
I am struggling to understand why the index.js -> console.log run even if I have the await in the value.
Can anyone point me in the right direction?
index.js
router.get('getValue','/display',async (ctx) => {
var myUtilfunction = require('../util')
var result = await myUtilfunction.getData()
console.log(result)
}
util.js
async function getData(){
var customObject =[]
var standardObject =[]
conn.describeGlobal(function (err,res){
if (err){return console.error(err)}
console.log('No of Objects ' + res.sobjects.length)
res.sobjects.forEach(function(sobject){
if (sobject.custom){
customObject.push(sobject)
}else{
standardObject.push(sobject)
}
})
console.log("Done")
})
return [customObject, standardObject]
}
Try this one
await, works inside async functions
router.get('getValue','/display', async (ctx) => {
var myUtilfunction = require('../util')
var result = await myUtilfunction.getData();
console.log(result)
});
function getData(){
return new Promise((resolve, reject) => {
resolve('result goes here');
});
}
You need to specify the function is async for the await to work.
Something like this:
router.get('getValue','/display', async (ctx) => {
var myUtilfunction = require('../util')
var result = await myUtilfunction.getData()
console.log(result)
}
Hope this helps :)
In your function getData(), I think you've missplaced your return statement. The return statement should be placed inside the callback function used for conn.describeGlobal().
As you actually write your getData(), the conn.describeGlobal() call seems to be an asynchronous treatment, so the return statement placed outside is probably executed before you pushed something in your arrays.
The consequence is that your router get an empty response from your getData() function then the promise made by await keyword is resolved with an empty answer.

Await - Async does not make function synchronous in behaviour

I am trying to run the following function which performs request.get to an array of URL's, and then write to an array, the whole operation needs to be synchronous. But my code is not synchronous, and prints different output each time:
var arrayPart = [];
fileDecode : async function(fileName,filePath){
for (a=0; a< arr.length; a++){
var partID = JSON.parse(arr[a].id)
var uri = listID[remainder]+'/download/'+'?id='+partID
await request.get(uri, this.onRequestDone);
}
onRequestDone: async function(err, resp, body){
await new Promise(function (resolve, reject) {
if(err){
reject(err)
}else{
const buf = Buffer.from(body)
console.log("buf", buf)
arrayPart.push(buf);
fs.writeFileSync('message.txt', arrayPart)
resolve(body)
}
});
}
}
my onRequestDone function does not behave correctly and prints buff differently.
The fact that request.get accepts second callback argument means that it it's callback-based and doesn't support promises. It doesn't return a promise to await. It generally doesn't make sense to provide async function as a callback in places where returned promise is ignored.
request-promise package can be used instead:
const request = require('request-promise');
...
const res = await request.get(uri);
const buf = Buffer.from(res.body);
...

Node.js returning an API response within an async function

I have written the following code to retrieve song lyrics from the apiseeds lyric api.
const apiseeds = require("apiseeds-lyrics");
const apiseedskey = "MY_API_KEY";
async function getLyrics(artistName, songName)
{
return await apiseeds.getLyric(apiseedskey, artistname, songName,
(response) => {
return response;
});
}
var artist = "Darius Rucker";
var title = "Wagon Wheel";
var lyrics = await getLyrics(artist, title)
console.log(lyrics);
I should also mention that the second block of code there is enclosed within an eventEmitter.on event with an asynchronous callback function.
Whenever the code runs, I get undefined in the console.
async and await can only be used to treat asynchronous functions that returns Promises, not callbacks. You should be able to transform your call to use Promises, or use another library.
The main reason we use await is to wait for the promise to resolve before continuing the code execution:
const result = await codeThatReturnsPromise()
console.log(result)
We could transform your code to this:
// async here means it returns a promise
async function getLyrics(artistName, songName)
{
return new Promise((resolve, reject) => {
apiseeds.getLyric(apiseedskey, artistname, songName, (response) => resolve(response))
})
}
var artist = "Darius Rucker";
var title = "Wagon Wheel";
var lyrics = await getLyrics(artist, title)
console.log(lyrics);

Resources