How to get async await / promise based response - javascript

So I have a code as below. There is a function that calls 2 axios requests to fetch some sample API data.
function fetch_records(){
var api_url1 = "https://api.github.com/users/mojombo"
var api_url2 = "https://api.github.com/users/defunkt"
axios.get(api_url1)
.then(function (response) {
console.log('Data1 received: ',response);
})
.catch(function (error) {
console.log(error);
})
axios.get(api_url2)
.then(function (response) {
console.log('Data2 received: ',response);
})
.catch(function (error) {
console.log(error);
})
}
And then I want to run this function fetch_records() as below
console.log('Script started');
fetch_records();
console.log('Script ended');
So that the output should be
Script started
... api response data ...
Script ended
But because Javascript is asynchronous, it always gives output as below
Script started
Script ended
... api response data ...
I belive async/await or promise is used to achieve the response I want but I am not sure how to use that exactly.

Just use async/await keywords, but remember JS always is JS.
async function fetch_records() { // a async function
var api_url1 = "https://api.github.com/users/mojombo"
var api_url2 = "https://api.github.com/users/defunkt"
// waterfall way
const data1 = await axios.get(api_url1); // await
console.log('Data1 received: ', data1);
const data2 = await axios.get(api_url2); // await
console.log('Data2 received: ', data2);
// parallel way
// const [data1, data2] = await Promise.all([
// axios.get(api_url1),
// axios.get(api_url2)
// ]);
// console.log(data1, data2);
}
(async () => {
try {
console.log('Script started');
await fetch_records(); // await a async function (Thenable object)
console.log('Script ended');
} catch(err) {
console.error(err);
}
})();

change your function to return promises:
function fetch_records() {
var api_url1 = "https://api.github.com/users/mojombo"
var api_url2 = "https://api.github.com/users/defunkt"
const promise1 = axios.get(api_url1)
.then(function (response) {
console.log('Data1 received: ',response);
})
.catch(function (error) {
console.log(error);
})
const promise2 = axios.get(api_url2)
.then(function (response) {
console.log('Data2 received: ',response);
})
.catch(function (error) {
console.log(error);
});
return [promise1, promise2];
}
now use promise.all :
Promise.all(fetch_records()).then(function(response) {
console.log(response[0], response[1]);
});

function fetch_records() {
var api_url1 = "https://api.github.com/users/mojombo"
var api_url2 = "https://api.github.com/users/defunkt"
return [
axios.get(api_url1),
axios.get(api_url2)
]
}
console.log('Script started');
Promise.all(fetch_records()).then(res => {
console.log(res);
console.log('Script ended');
})
Promise.all will wait till all promises are resolved, more about it

function fetch_records() {
var api_url1 = "https://api.github.com/users/mojombo";
return new Promise((resolve, reject) => {
axios
.get(api_url1)
.then(function(response) {
console.log("Data1 received: ", response);
resolve(response);
})
.catch(function(error) {
console.log(error);
reject(error);
});
});
}
Use with Async/Await :
async function getData() {
let data = await fetch_records();
console.log("Fetch Records :: ", data);
}

Related

Promise.all with "nested" axios request

I'm facing a small problem with Promise.all and axios. I read a lot of documentation on "how to do it", but still I did not get what I want.
Basically, I want to execute multiple axios requests and when they all finished, I want to do something…
My code is:
async ajaxPromise() {
let me = this;
const someFunction = () => {
return new Promise(resolve => {
setTimeout(() => resolve('222'), 100)
})
}
async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
debugger;
await callback(array[index], index, array);
}
}
let urlObjects = ["https://url1.com", "https://url2.com", "https://url3.com"];
let requestArr = [];
await asyncForEach(urlObjects, async (data) => {
let waitForThisData = await someFunction(data);
requestArr.push(
axios.get(data)
.then(function (response) {
console.log("THEN AXIOS")
})
.catch(function (response) {
console.log("CATCH AXIOS")
})
);
});
Promise.all([
requestArr
])
.then(function (results) {
console.log("THEN PROMISE")
})
.finally(() => {
console.log("FINALLY PROMISE")
})
.catch(function (error) {
console.log("CATCH PROMISE")
});
},
What happens, is console.log("THEN PROMISE") is displayed before all the console.log("THEN AXIOS"). What I would like to do: display the console.log("THEN PROMISE") after the console.log("THEN AXIOS").
Where am I wrong ?
Thanks for your help.

how to wait for writeFile or createWriteStream function to complete in node js?

I am stuck in code I tried different way to wait for write file in node.js but it does not wait .
Below is code
app.post('/createEmp',async (req,res) => {
console.log("Inside createEmp()");
var response = await createEmp(req.body);
console.log(response);
});
async function createEmpFile(fileContentObj){
var response = {};
console.log("filePath :"+filePath);
return new Promise(function(resolve,reject){
fs.writeFile(filePath, fileContentStr, function (err) {
if (err){
console.log("err :"+err);
reject(err);
}
else {
console.log('Saved!');
fileSavedFlag = true;
response.result = fileSavedFlag;
console.log(response);
resolve(response)
};
});
}); // end of promise
/*return new Promise(function(resolve,reject) {
const file = fs.createWriteStream(filePath)
file.write(fileContentStr)
file.end();
file.on("finish", () => { fileSavedFlag = true; resolve(response) });
file.on("error", () => { resolve(response) });
}); */
}
On node js console I can see response but when I called using postman I dont get any response it
Your post route should have res.send as follows
app.post('/createEmp',async (req,res) => {
console.log("Inside createEmp()");
var response = await createEmp(req.body);
console.log(response);
res.send(response)
});

How is this possible? Things should get printed but they dont

I don't understand how the console.logs not getting printed.
import { GenericRepository, getGenericRepository } from '../src/database/repository/GenericRepository';
import { start, stop } from '../src/index';
import request from 'request';
const baseUrl = 'http://localhost:3200/';
const getTable = async (tableName: string) => {
const data = {
'tableName': 'tableName'
};
const header = {
url: baseUrl + 'table',
method: 'POST',
json: true
};
console.log('hello');
request.post({
url: 'http://localhost:3200/getTable',
body: data,
json: true
}, (error, response, body) => {
console.log('getting angry');
if (error) {
console.error('error: ', error);
} else {
console.log(response);
}
});
await new Promise((resolve, reject) => {
request.post({
url: 'http://localhost:3200/getTable',
json: data
}, (error, response, body) => {
console.log('getting angry');
if (error) {
console.error('error: ', error);
reject(error);
} else {
console.log(response);
resolve('response' + response);
}
});
})
}
describe('A suite', function () {
beforeAll(async done => {
// await start()f.catch(error => { console.log(error); });
done();
});
afterAll(() => {
console.log('afterall')
});
it('contains spec with an expectation', async done => {
console.log('spec executed')
getTable('supply').then(result => {
console.log('result: ', result)
}).catch(error => {
console.log('error', error);
});
console.log('after getTable')
done();
// expect(table.length).toBeGreaterThan(0);
});
});
Neither of these are getting printed:
console.log('getting angry');
console.error('error: ', error);
console.log(response);
console.log('result: ', result);
console.log('result: ', result);
console.log(response);
what actually gets printed is:
Started
spec executed
hello
after getTable
.afterall
Please help me understand what's going on!.
I tested it with postman the server is working properly.
I would expect that the request would return the same result as the postman does.
it('contains spec with an expectation', async done => {
console.log('spec executed')
getTable('supply').then(result => {
console.log('result: ', result)
}).catch(error => {
console.log('error', error);
});
console.log('after getTable')
done();
// expect(table.length).toBeGreaterThan(0);
});
This code says to synchronously do all of the following: Call getTable, which returns a promise. Then schedule some stuff to be done when (if) that promise resolves. Then call done(), thus ending the test. Since the test has been ended, the async stuff in getTable doesn't happen, nor do the .then callbacks.
Instead, you need to wait until getTable's promise is done resolving before you finish the test. Also, since you're already in an async function, you don't need to be using .then callbacks, and don't need to use done() since jasmine knows to wait until the async function's promise finishes. For example:
it('contains spec with an expectation', async () => {
console.log('spec executed')
try {
const result = await getTable('supply')
console.log('result: ', result)
} catch (error) {
console.log('error', error);
}
console.log('after getTable')
});
You're almost there, but your call to done() is not in the right place. The test will run, launch the Promise and then immediately notify that it is done() before the promise has chance to resolve or reject.
Try moving the done() to within the then and catch blocks:
it('contains spec with an expectation', async done => {
getTable('supply').then(result => {
console.log('result: ', result)
done()
}).catch(error => {
console.log('error', error)
done.fail(error)
});
});

Promise returns wrong value

In my code I try to assign a value to json variable to return it after (because I can't return it from the anon. function).
As my function is async, because it sends requests (maybe someone knows how to make it sync? I didn't plan to make it asynchronous), I've added await before the request (https.get).
I've been trying to get value from the Promise, but it's always undefined, even though I've awaited the async function.
Here's a code:
async function get_users() {
const https = require('https');
var token = '...';
var json = undefined;
await https.get('...', (resp) => {
let data = '';
resp.on('data', (chunk) => {
data += chunk;
});
resp.on('end', () => {
json = JSON.parse(data)['response']['items'];
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
return json;
}
get_users().then(function(result) {
console.log(result);
});
Return a Promise and resolve it, when the end event is called, otherwise reject it in case of an error occurred:
async function get_users() {
const https = require('https');
const token = '...';
return new Promise((resolve, reject) => {
https.get('...', resp => {
let data = '';
resp.on('data', chunk => {
data += chunk;
});
resp.on('end', () => {
let json;
try {
json = JSON.parse(data)['response']['items'];
} catch (e) {
reject(e);
};
resolve(json);
});
}).on("error", err => reject(err));
});
}
get_users().then(result => console.log(result));
Please refer my below code.I had issues with getting responses from Promises too.But i finally got it to work.Here's the code:
var output;
var rp = require('request-promise-native');
var myJSONObject = {
"inputs": [{
"name": "<name>",
"value": < value >
}]
};
var orchName = 'TEST05';
postData = JSON.stringify(myJSONObject);
return networkCall(postData, orchName).then((response) => {
console.log('response is' + response)
}).catch((response) => {
console.log(`ERROR: ` + response);
});
function networkCall(postData, orchName) {
return new Promise((resolve, reject) => {
var options = {
method: 'post',
uri: '<URL>',
body: postData,
auth: {
'user': 'usr',
'pass': 'pwd'
},
json: true
};
return rp(options)
.then(body => {
var response = body;
resolve(response);
})
.catch(err => {
console.log('FAILED' + err);
reject(err);
});
});
}
This way your code can run in Synchronous Flow.If the return value is undefined,then,what might have probably happened is that the calling function would have finished executing even before the called function returns its response.But the above approach would work just fine.

unexpected identifier when using await/async in nodejs

I'm getting unexpected identifier when i use async or await in nodejs. I'm on node version 8.5.0. Completely blocked on this. Is there anyway to fix this?
async function methodA(options) {
rp(options)
.then(function (body) {
serviceClusterData = JSON.parse(body);
console.log("Step 2");
console.log("Getting cluster details from zookeeper");
})
.catch(function (err) {
console.log("Get failed!");
});
}
await methodA(options);
console.log("Step 3!");
Tried this after first answer :
var serviceClusterData = "";
console.log("Step 1!");
////////////////////
async function methodA(options) {
await rp(options)
.then(function (body) {
serviceClusterData = JSON.parse(body);
console.log("Step 2");
console.log("Getting cluster details from zookeeper");
})
.catch(function (err) {
console.log("Get failed!");
});
}
methodA(options);
console.log("whoops Step 3!");
Still gets out of order :(
Step 1
Step 3
Step 2
You can't use await outside of an async function.
async function methodA(options) {
await rp(options)
.then(function (body) {
serviceClusterData = JSON.parse(body);
console.log("Step 2");
console.log("Getting cluster details from zookeeper");
})
.catch(function (err) {
console.log("Get failed!");
});
}
methodA(options);
console.log("Step 3!");
'use strict'
function methodA(options) {
return new Promise(resolve => {
setTimeout(() => {
console.log(1)
resolve(true);
}, 2000);
})
}
//Sync Declartion
async function test() {
//Await declaration
await methodA({});
console.log(2);
}
test();
It seems there's is some syntax error in your code. Above code works in 8.5.0
Reference https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function

Categories