Providing callback in a _.forEach construct - javascript

(Working in the Postman environment) it was detected that the following code runs through all the url requests without printing the result.
_.forEach(
urls,
function (myUrl) {
pm.sendRequest({
url: myUrl,
method: 'GET',
header: {
'content-type': 'application/json'
}
}, function (err, res) {
console.log(res)
});
}
)
pm.environment.set(`sections`,sections);
}
Is there any way to provide a callback within forEach, might appear something like given below code. Or is there any alternative to it.
function callback() {
console.log('callback');
}
_.forEach(
urls,
function (myUrl,callback) {
pm.sendRequest({
url: myUrl,
method: 'GET',
header: {
'content-type': 'application/json'
}
}, function (err, res) {
console.log(res)
});
}
)
pm.environment.set(`sections`,sections);
}
I had initially thought that the response handling function at the end would take care of that but it doesn't.

Found it better to branch out the logic into another function getUrl and pass the callback into it.
Following code works:
_.forEach (
urls,
function (myUrl) {
getUrl(myUrl,function (err,res) {
if (err) {
console.log(err);
} else {
console.log(JSON.stringify(res));
}
});
}
);
function getUrl(myUrl, callback) {
var call = {
url: myUrl,
method: 'GET',
header: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
}
};
pm.sendRequest(
call,
function (err, res) {
callback (err,res);
}
);
}

Related

Variable is not updating after ajax request

I have the code below which is in a Vue script.
user_id = 100; //sample data
$.ajax({
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
type: "GET",
url: '/user',
success: function (user) {
user_id = user.user_id;
console.log(user_id); //returns 1
},
error: function (result) {
}
});
console.log(user_id); //returns 100 not 1
I want to be able to store the value that is resulted from the ajax request which is 1. However, when I console.log at the end of the script it returns 100 not 1. I think that I need to use a promise/callback to solve this but I am not sure how/what I need to do. Can someone help me?
Define your method and return as a promise.
function getUsers() {
return new Promise((resolve, reject) => {
$.ajax({
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
type: "GET",
url: '/user',
success: function (data) {
resolve(data);
},
error: function (error) {
reject(error);
}
});
});
}
You would call the method as below.
getUsers().then((data) => {
console.log(data); /* you will get the new data returned from ajax.*/
}).catch((error) => {
console.log(error);
});
This is how you can promisify callbacks in general:
let doXWithCallback = callback => {
// do x...
callback();
};
let doXPromisified = () => new Promise(doXWithCallback);
doXWithCallback(() => console.log('do x with callback'));
doXPromisified().then(() => console.log('do x promisified'));
For your example specifically:
let doRequest = () =>
new Promise((resolve, reject) =>
$.ajax({
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
type: "GET",
url: '/user',
success: user => resolve(user.user_id),
error: reject(),
}));
doRequest.then(userId => console.log('userId is', userId));

nodejs promise best way to implement from settimeout

I have the following functions working in nodejs, but I am using a setTimeout rather than a promise. If the createchange takes longer than the timeout I have, my code fails but does not catch the error correctly.
How would I substitute or change the following function(s) to work with a promise, so deploychange waits for createchange to complete, before continuing through the code?
I've tried a couple things but nothing seems to work. Not sure which function I should redo either for the most effective solution.
Any help would be appreciated.
First function
function createchange(accessToken){
const data = {
templateName: "Template 1",
summary: "Deploy Change",
configurationItems: [
config_item
],
wasEnvUsedForTesting: false,
environment: test_env
};
rp({
url: dbConfig.cmas_url,
resolveWithFullResponse: true,
method: 'POST',
json: true,
auth: {
bearer: accessToken
},
body: data,
headers: {
'Content-Type': 'application/json',
'apikey': dbConfig.consumer_key,
},
}, function(err, res) {
if(err){
console.log(err.body);
}else{
console.log(res.body);
crq = res.body.changeid;
}
});
}
2nd function
function run() {
deploychange();
setTimeout(function(){ deployinsert(); }, 7500);
deployrun();
}
3rd function
function deploychange (callback) {
if (req.body.deployEnv == "PRD"){
getToken(function(accessToken) {
createchange(accessToken);
})};
}
According to the request-promise documentation, rp returns a promise.
You can actually convert your createChange function to return a promise like so:
const createchange = accessToken => {
const data = {
templateName: 'Template 1',
summary: 'Deploy Change',
configurationItems: [config_item],
wasEnvUsedForTesting: false,
environment: test_env
};
return rp({
url: dbConfig.cmas_url,
resolveWithFullResponse: true,
method: 'POST',
json: true,
auth: {
bearer: accessToken
},
body: data,
headers: {
'Content-Type': 'application/json',
apikey: dbConfig.consumer_key
}
});
};
You can then call your function with the await keyword.
await createchange(accessToken);
Make sure that the function using await is marked with async
You can also write it like this:
createchange(accessToken)
.then(({changeId}) => {
// Do someth with the changeId
})
.catch(/* Error handling */)

How do I pass the response of one API as a request param in another API using Request-Promise

I want to pass the response received from one API as a request parameter in another API using Request-Promise NodeJs module. Can someone pls help me in this? I am giving a brief of the sample code below:
var Sequence = {
test1: function (param) {
return request({
"method": "POST",
"uri": baseURL+"/v1/" + userID + "/test/info/",
"json": true,
"headers": {
"Accept": "application/json",
},
}).then(function (result) {
return result.pairingInfo // I want to use this pairinfInfo param in another request
})
test2 : function (param) {
return request({
"method": "POST",
"uri": baseURL+"/v1/passenger/" + userID + "/test/test/",
"json": true,
"headers": {
"Accept": "application/json",
},
"qs": {
**"pairingInfo": pairingInfo**,//This pairingInfo would come from the returned result.pairingInfo of test 1 API call
}
})
}
},
How can I achieve this?
You can use this because you have a return statement in the test1() method. So, just trigger it to get it:
"qs": {
"pairingInfo": this.test1(),
}
Sequence.test1(param)
.then(function(pairingInfo) {
Sequence.test2(pairingInfo) ;
});
// You are returning the paringInfo with the first promise, so you can use it in the .then() method.
Use this function:
const sequence = async (baseURL, userID) => {
try {
let options1 = {
method: 'POST',
uri: baseURL + '/v1/' + userID + '/test/info/',
json: true,
headers: {
Accept: 'application/json'
}
};
let pairingInfo = await request(options1);
if (pairingInfo) {
let options2 = {
method: 'POST',
uri: baseURL + '/v1/passenger/' + userID + '/test/test/',
json: true,
headers: {
Accept: 'application/json'
},
qs: {
pairingInfo: pairingInfo //This pairingInfo would come from the returned result.pairingInfo of test 1 API call
}
};
await request(options2);
return true;
} else {
console.log('Request 1 failed');
return false;
}
} catch (err) {
console.error(err);
return false;
}
};

Make another ajax call to get headers before each actual ajax call - jquery

I have to make an async call which uses cookie to get bearer token which has to be passed to make actual ajax call for the resource.
And I have written the following code which works awesome and get's me the result.
Can I use ajaxPrefilter or beforeSend options to get the tokens, I tried to find documentation for ajaxPrefilter which says it accepts a function, but does that waits for that function to be finished before making actual call?
Token retrieval function
function getTokenUsingCookieAsync() {
return new Promise(function (resolve, reject) {
$.ajax('/retrieve-token').done(function (result) {
resolve(result.token);
}).fail(function (message) {
reject(message);
});
});
}
Actual execute function:
function execute(url, method, data) {
var deferred = $.Deferred();
getTokenUsingCookieAsync().then(function (response) {
var reqSettings = {
async: true,
url: url,
cache: false,
type: method,
headers: {
Authorization: 'Bearer '+ response,
},
contentType: 'application/json; charset=utf-8',
dataType: 'json',
data: data ? JSON.stringify(data) : null
};
$.ajax(reqSettings).done(function (result) {
deferred.resolve(result);
}).fail(function (message) {
deferred.reject(message);
});
}).catch(function (message) {
deferred.reject(message);
});
return deferred.promise();
}
So the following pseudo code is possible or not?
$.ajaxPrefilter((options) => {
$.ajax('/retrieve-token').done((result) => {
options.headers = {
Authorization: `Bearer ${result}`
};
});
});
$.ajax('actual-url')
.done(whatever);

Node + ES6: How to use Promise.all with async requests?

I have a method called fetchMerchantData which calls 3 other async methods. I'm trying to use Promise so that it doesn't call resp.direct(301, ...) until all the requests are finished but it's not working.
function fetchOauth2Token(authorizationCode, resp) {
...
request({
url: `https://connect.squareup.com/oauth2/token`,
method: "POST",
json: true,
headers: oauthRequestHeaders,
form: oauthRequestBody,
}, (error, oauthResp, body) => {
if (body.access_token) {
Promise.resolve(fetchMerchantData(body.access_token, body.merchant_id)).then(() => {
console.log("last!"); //<--------------------- this is printing first
resp.redirect(
301,
`myurl.com/blah`
);
});
;
} else {
// TODO find out what to do on failure
resp.redirect(301, `myurl.com/?error=true`);
}
})
}
function fetchMerchantData(access_token, merchant_id){
const updates = {};
request({
url: `https://connect.squareup.com/v1/me/locations`,
method: "GET",
json: true,
headers: {
Authorization: `Bearer ${access_token}`,
Accept: 'application/json',
"Content-Type": "application/json",
},
}, (error, response) => {
if (!error) {
const locations = response.body;
Promise.all([
saveMerchant(merchant_id, access_token, locations),
saveLocations(merchant_id, locations),
installWebhookForLocations(access_token, locations),
]).then(values => {
console.log("first!"); //<--------------------- this is printing last
return Promise.resolve("Success");
})
}
});
}
And here's an example of the saveMerchant method which calls firebase:
function saveMerchant(merchant_id, access_token, locations) {
const merchantRef = database.ref('merchants').child(merchant_id);
const location_ids = locations.map(location => location.id);
merchantRef.update({
access_token,
location_ids,
});
}
How would I synchronize this?
== UPDATE ==
This is how my installWebhookForLocations method looks:
function installWebhookForLocations(access_token, locations){
const locationIds = locations.map(location => location.id);
locationIds.forEach((locationId) => {
request({
url: `https://connect.squareup.com/v1/${locationId}/webhooks`,
method: "PUT",
json: true,
headers: {
Authorization: `Bearer ${access_token}`,
Accept: 'application/json',
"Content-Type": "application/json",
},
body: ["PAYMENT_UPDATED"],
}, (error) => {
if (!error){
console.log(`Webhook installed for ${locationId}`);
}
});
});
}
Here is an example of saveMerchant that would use a promise.
function saveMerchant(merchant_id, access_token, locations) {
return new Promise(function (resolve, reject) {
const merchantRef = database.ref('merchants').child(merchant_id);
const location_ids = locations.map(location => location.id);
merchantRef.update({
access_token,
location_ids,
}, function (error) {
if (error) return reject(error);
resolve();
});
});
}
To make the above easier, there is a nice Promise library called Bluebird, it has a promisify utility, that you could apply to firebird update method.
Also for your second question were your using forEach, bluebird has a nice utility function called map that you could use instead.

Categories

Resources