I am trying to create a dictionary object of the response json's using postman's pm api sendRequest.
Wrote a recursive function to get all the responses but the problem is the response dictionary object population happens way before even the response comes back.
Is there any way to wait the dictionary population before each of the respective response is received so as to capture the response within the dictionary object ?
var respDictionary = {};
getResponses (listOfUrls);
console.log("respDictionary: ");
console.log(respDictionary);
function getResponses(urlList) {
if (typeof urlList === 'string') {
urlList = urlList.split(' ');
}
_url = urlList[0];
var call = {
url: _url ,
method: 'GET',
header: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
};
urlList.splice(0, 1);
pm.sendRequest(
call,
function (err, res) {
if (err) {
console.log(err);
} else {
if (urlList.length === 0) {
return;
}
try {
respDictionary[_url] = res.json();
} catch (e) {
console.log(err);
}
getResponses(urlList);
}
});
console.log(respDictionary);
}
Output is:
respDictionary:
Object:{}
//further, pm request responses are listed
Apart from the other answer(s), following simple approach also works well instead of recursion:
_.forEach (
urls,
function (urls) {
getAPI(url,function (url,schema,err) {
if (!err) {
respDictionary[url]=resp.json();
console.log(schema);
} else {
console.log(err);
}
pm.environment.set('respDictionary', JSON.stringify(respDictionary));
});
}
);
function getAPI(url, callback) {
var _url = '{{BP_SERVER}}/' + urls;
var call = {
url: _url,
method: 'GET',
header: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
};
pm.sendRequest(
call,
function (err, res) {
if (!err) {
callback(urls,res.json());
} else {
callback(urls,'',err);
}
}
);
}
You do not understand JavaScript asynchrounous handling. Maybe the following will help:
Event loop video
Promises
Event loop documentation (video is easier)
Your code will work if you use promises:
function getResponses(urlList) {
if (typeof urlList === 'string') {
urlList = urlList.split(' ');
}
return Promise.all(
urlList.map(
function(url){
return {
url: url ,
method: 'GET',
header: {
//not sure where token comes from
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
};
}
).map(
function(call){
return new Promise(
function(resolve,reject){
pm.sendRequest(
call,
function (err, res) {
if (err) {
reject(err);
} else {
resolve([call.url,res.json()]);
}
});
}
)
.then(
undefined
,function(err){
//if something goes wrong we will still return something
return [call.url,{error:err}];
}
)
}
)
)
.then(
function(results){
return results.reduce(
function(acc,result){
acc[result[0]] = result[1];
}
,{}
);
}
)
}
getResponses (listOfUrls)
.then(//this will always succeed, failed items have {error:something}
function(results){
console.log("results:",results);
}
);
console.log("this comes before results");
The code above will cause all request to happen at once, this may not be the desired behavior, I have written a throttle method that is part of some library functions that may come in handy. You can apply the throttle to your code so it will only have max amount of connections:
const max = 10;//maximum 10 active connections
function getResponses(urlList) {
const throttled = throttle(max);
if (typeof urlList === 'string') {
urlList = urlList.split(' ');
}
return Promise.all(
urlList.map(
function(url){
return {
url: url ,
method: 'GET',
header: {
//not sure where token comes from
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
};
}
).map(
throttled(//only max amount of connections active at any time
function(call){
return new Promise(
function(resolve,reject){
pm.sendRequest(
call,
function (err, res) {
if (err) {
reject(err);
} else {
resolve([call.url,res.json()]);
}
});
}
)
.then(
undefined
,function(err){
//if something goes wrong we will still return something
return [call.url,{error:err}];
}
)
}
)
)
)
.then(
function(results){
return results.reduce(
function(acc,result){
acc[result[0]] = result[1];
}
,{}
);
}
)
}
getResponses (listOfUrls)
.then(//this will always succeed, failed items have {error:something}
function(results){
console.log("results:",results);
}
);
console.log("this comes before results");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With