The following is my code:
async function asynccall() {
//POST request (create order)
var data = JSON.stringify({
merchant_urls: {
terms: "https://www.example.com/terms.html",
checkout: "https://atelierdecosmetique.herokuapp.com/checkout",
confirmation: "https://atelierdecosmetique.herokuapp.com/confirmation",
push: "https://www.example.com/api/push",
},
});
var config = {
method: "post",
url: "https://api.playground.klarna.com/checkout/v3/orders/",
headers: {
"Content-Type": "application/json",
Authorization: "",
},
data: data,
};
var orderid = Postrequest.data.order_id;
//GET Request (read order)
var axios = require("axios");
var data1 = JSON.stringify({
merchant_urls: {
confirmation: "https://www.example.com/confirmation.html" + Postrequest.data.order_id,
},
});
var config1 = {
method: "get",
url: "https://api.playground.klarna.com/checkout/v3/orders/",
headers: {
"Content-Type": "application/json",
Authorization:
},
data: data1,
};
//The calls as variables
var Postrequest = await axios(config);
var Getrequest = await axios(config1);
console.log(Getrequest.data.merchant_urls.confirmation)
app.get("/checkout", function(req, res) {
res.render("checkout.ejs", {
datapost: Postrequest.data.html_snippet
})
});
app.get("/confirmation", function(req, res) {
res.render("confirmation.ejs", {
dataget: Getrequest.data.html_snippet
});
});
}
asynccall();
My problem with this code is that the Postrequest.data.order_id is not shown in the GET request's merchant_urls.confirmation URL when I console log it at the end of the code. It should return the confirmation page URL with the order_id response from the POST request at the end. How could I solve this? I know it has to do with asynchronous and synchronous code? I'm stuck and really need this to work.
You need to get the results of the first request before using the returned data in the second.
async function asynccall() {
var axios = require("axios");
//POST request (create order)
var data = JSON.stringify({
merchant_urls: {
terms: "https://www.example.com/terms.html",
checkout: "https://atelierdecosmetique.herokuapp.com/checkout",
confirmation: "https://atelierdecosmetique.herokuapp.com/confirmation",
push: "https://www.example.com/api/push",
},
});
var config = {
method: "post",
url: "https://api.playground.klarna.com/checkout/v3/orders/",
headers: {
"Content-Type": "application/json",
Authorization: "",
},
data: data,
};
var Postrequest = await axios(config);
var orderid = Postrequest.data.order_id;
//GET Request (read order)
var data1 = JSON.stringify({
merchant_urls: {
confirmation: "https://www.example.com/confirmation.html" + Postrequest.data.order_id,
},
});
var config1 = {
method: "get",
url: "https://api.playground.klarna.com/checkout/v3/orders/",
headers: {
"Content-Type": "application/json",
Authorization: ""
},
data: data1,
};
//The calls as variables
var Getrequest = await axios(config1);
console.log(Getrequest.data.merchant_urls.confirmation)
app.get("/checkout", function(req, res) {
res.render("checkout.ejs", {
datapost: Postrequest.data.html_snippet
})
});
app.get("/confirmation", function(req, res) {
res.render("confirmation.ejs", {
dataget: Getrequest.data.html_snippet
});
});
}
asynccall();
Related
I have some code that looks like this in Next JS
const resApp = await fetch('/api/club/createsignalapp', {
body: JSON.stringify({
name: event.target.name.value,
}),
headers: {
'Content-Type': 'application/json',
},
method: 'POST',
})
const appResult = await resApp.json()
--createsignalapp
export default async (req, res) => {
var mydata
var createApp = function (data) {
var headers = {
'Content-Type': 'application/json; charset=utf-8',
Authorization: `Basic APIKKEY`,
}
var options = {
host: 'onesignal.com',
port: 443,
path: '/api/v1/apps',
method: 'POST',
headers: headers,
}
var https = require('https')
var myreq = https.request(options, function (myres) {
myres.on('data', function (data) {
mydata = JSON.parse(data)
res.statusCode = 200
res.json({
response: {
boolean: true,
alert: '',
message: '',
},
data: mydata
})
})
})
myreq.on('error', function (e) {
console.log(e)
})
myreq.write(JSON.stringify(data))
myreq.end()
}
var message = {
name: req.body.name
}
createApp(message)
}
This hits the error API resolved without sending a response for /api/club/createsignalapp, this may result in stalled requests.
I'm not sure how to do this correctly as i'm getting confused with the awaits and asyncs and requests everywhere.
Happy to hear suggestions.
Thanks
I can't seem to figure out how to get my 2nd http post to work "queuecallback". It looks like the problem is specific to how i set the headers. Headers = my_headers. It works when i hard code it but not when i try to call it dynamically. Any help would be greatly appreciated. Thanks!
const axios = require('axios');
const queuecallback = require('axios');
var my_token;
var my_formated_token;
var my_headers;
var myJSON;
function connectToAgentHandler(agent) {
axios({
method: 'post',
url: 'https://myapi.com/AuthorizationServer/Token',
data: {
username: 'myusername',
password: 'mypassword',
grant_type: 'password'
},
headers: {'Authorization': 'basic 123456789Aghtiaqq111kkksksksk111'}
}
)
.then((result) => {
my_token = result.data.access_token;
console.log("Token:", my_token);
my_formated_token = 'bearer ' + my_token;
console.log("Formated Token:", my_formated_token);
var my_headers = "{'Authorization': '" + my_formated_token + "'}";
console.log("My Headers:", my_headers);
});
//lets execute the callback from an agent
queuecallback({
method: 'post',
url: 'https://myapi.com/go',
data: {
phoneNumber: '1111111111',
skill: '12345'
},
headers: my_headers
}
)
.then((result) => {
console.log("your contactId is:", result.data.contactId);
});
}
});
It's not necesseray to require two axios :
const axios = require('axios');
const queuecallback = require('axios');
Your problem is that you set the headers in the first call
var my_headers = "{'Authorization': '" + my_formated_token + "'}";
axios is a asynchronous function so the queuecallback is called directly after the first axios call (which is not finished). You can use async function to "wait" the end of the first call :
const axios = require('axios');
async function connectToAgentHandler(agent) {
try {
let result = await axios({
method: 'post',
url: 'https://myapi.com/AuthorizationServer/Token',
data: {
username: 'myusername',
password: 'mypassword',
grant_type: 'password'
},
headers: {
'Authorization': 'basic 123456789Aghtiaqq111kkksksksk111'
}
});
const token = `bearer ${result.data.access_token}`;
const headers = {
'Authorization': token
};
result = axios({
method: 'post',
url: 'https://myapi.com/go',
data: {
phoneNumber: '1111111111',
skill: '12345'
},
headers
});
console.log("your contactId is:", result.data.contactId);
} catch (err) {
// process error
}
};
I have several API Get request at once in nodejs. Each API have new data every couple minutes.
var express = require('express');
var router = express.Router();
var request = require("request");
let value1, value2, bodyData1, bodyData2;
var options = { method: 'GET',
url: 'https://api.example.com/data1',
qs:
{
valueType: 'MAXIMUM'
},
headers:
{
authorization: 'ABC123456',
accept: 'application/json; charset=utf-8' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
bodyData1 = JSON.parse(body);
value1 = bodyData1.value;
});
var options = { method: 'GET',
url: 'https://api.example.com/data2',
qs:
{
valueType: 'MAXIMUM'
},
headers:
{
authorization: 'ABC123456',
accept: 'application/json; charset=utf-8' } };
request(options, function (error, response, body) {
if (error) throw new Error(error);
bodyData2 = JSON.parse(body);
value2 = bodyData2.value;
});
router.get('/', function(req, res, next) {
res.render('home', {valueA : value1, valueB: value2});
});
module.exports = router;
I want to know if it is possible to combine them into one function?
Any other things I should concern?
It is possible if you have promises which is currently not the case. You have to wrap your request() call in a Promise. You can do it manually with a custom function requestToPromise.
You can then use Promise.all to call multiple promises in parallel.
function requestToPromise(options) {
return new Promise((resolve, reject) => {
request(options, (error, response, body) => {
if (error) return reject(error);
resolve(body);
});
});
}
var optionsRequest1 = {
method: "GET",
url: "https://api.example.com/data1",
qs: {
valueType: "MAXIMUM"
},
headers: {
authorization: "ABC123456",
accept: "application/json; charset=utf-8"
}
};
var optionsRequest2 = {
method: "GET",
url: "https://api.example.com/data2",
qs: {
valueType: "MAXIMUM"
},
headers: {
authorization: "ABC123456",
accept: "application/json; charset=utf-8"
}
};
var requestPromise1 = requestToPromise(optionsRequest1);
var requestPromise2 = requestToPromise(optionsRequest2);
Promise.all([requestPromise1, requestPromise2]).then(results => {
var [resultPromise1, resultPromise2] = results;
}).catch(error => {
//handle error
});
Instead of using the custom function requestToPromise you can also use util.promisify
const util = require('util');
const requestAsync = util.promisify(request);
Promise.all([requestAsync(optionsRequest1), requestAsync(optionsRequest2)]).then(results => {
var [resultPromise1, resultPromise2] = results;
}).catch(error => {
//handle error
});
You can use Redis cache to store data in memory for fast retrieval and fetch from memory very quickly.
Also, after some interval, you can add them to a database through bulk creation. It will decrease your database call.
// Example in sequilize
await db.table_name.bulkcreate([ {0bj1}, {obj2}..,{obj3 } ]);
I am trying to invoke services in node express in a loop. But the problem is that before all the services are invoked, the remaining code is getting executed.
I tried some options with Promise, async/await but they didn't work.
Basically I need to invoke the service in a synchronous way.
I have created 2 mock services in JSON stub. In the first service response, I will get an array of vehicles. Once I got this, I need to update one more value in each array by calling another service.
Here the problem I faced is that the 2nd service is not called synchronously.
const express = require('express');
const request = require("request");
const router = express.Router();
router.get('/make', (req, res) => {
var options = {
headers: {
'Content-Type': 'application/json',
'JsonStub-User-Key': 'ddc159a0-5aa8-4a38-a0f1-913e4d768b56',
'JsonStub-Project-Key': '34ba28a9-471c-435d-ab61-b7732c9583c6'
},
method: "GET",
json: true,
strictSSL : false,
url: `http://jsonstub.com/vehicle/make`
};
request(options, function(error, response, body) {
if (body){
checkModelType(body);
res.status(200).json(body).end();
} else {
console.log("REST Request timeout: ", JSON.stringify(error));
res.status(400).json('Error').end();
}
});
});
function checkModelType(response){
let vehicleList = response.vehicleList;
console.log("--->"+vehicleList.length);
for(var i = 0;i<vehicleList.length;++i){
const modelType = findModel();
vehicleList[i].modelType = modelType;
}
console.log("Updated Vehicle List:"+JSON.stringify(vehicleList));
}
const findModel = () =>{
var options = {
headers: {
'Content-Type': 'application/json',
'JsonStub-User-Key': 'ddc159a0-5aa8-4a38-a0f1-913e4d768b56',
'JsonStub-Project-Key': '34ba28a9-471c-435d-ab61-b7732c9583c6'
},
method: "GET",
json: true,
strictSSL : false,
url: `http://jsonstub.com/vehicle/details`
};
request(options, function(error, response, body) {
if (body){
console.log("Model Type-->"+body.output.modelType);
return body.output.modelType;
} else {
console.log("REST Request timeout: ", JSON.stringify(error));
}
});
}
module.exports = router;
Response :
-----------
PS F:\workSpace_Node\TestApp> node app.js
server running at 9086
--->4
Updated Vehicle List:[{"make":"Audi","model":"A3","vin":"QVFCFQT7894563214"},{"make":"Audi","model":"A4","vin":"ASECFQT7894563214"},{"make":"Audi","model":"Q5","vin":"QWECFQT7894993214"}]
Model Type-->SD
Model Type-->SD
Model Type-->SD
Expected result :
[{"make":"Audi","model":"A3","modelType":"SD", "vin":"QVFCFQT7894563214"},{"make":"Audi","model":"A4","modelType":"SD","vin":"ASECFQT7894563214"}]
You can switch to request-promise library instead of request and then go with some async\await:
const express = require('express');
const request = require('request-promise'); // switched library
const router = express.Router();
router.get('/make', async (req, res) => {
var options = {
headers: {
'Content-Type': 'application/json',
'JsonStub-User-Key': 'ddc159a0-5aa8-4a38-a0f1-913e4d768b56',
'JsonStub-Project-Key': '34ba28a9-471c-435d-ab61-b7732c9583c6'
},
method: "GET",
json: true,
strictSSL : false,
url: `http://jsonstub.com/vehicle/make`
};
const body = await request(options);
if (body) {
await checkModelType(body);
res.status(200).json(body).end();
} else {
console.log("REST Request timeout: ", JSON.stringify(error));
res.status(400).json('Error').end();
}
});
async function checkModelType(response){
let vehicleList = response.vehicleList;
console.log("--->"+vehicleList.length);
for(var i = 0;i<vehicleList.length;++i){
const modelType = await findModel();
vehicleList[i].modelType = modelType;
}
console.log("Updated Vehicle List:"+JSON.stringify(vehicleList));
}
const findModel = async () =>{
var options = {
headers: {
'Content-Type': 'application/json',
'JsonStub-User-Key': 'ddc159a0-5aa8-4a38-a0f1-913e4d768b56',
'JsonStub-Project-Key': '34ba28a9-471c-435d-ab61-b7732c9583c6'
},
method: "GET",
json: true,
strictSSL : false,
url: `http://jsonstub.com/vehicle/details`
};
const body = await request(options);
if (body){
console.log("Model Type-->"+body.output.modelType);
return body.output.modelType;
} else {
console.log("REST Request timeout: ", JSON.stringify(error));
}
}
module.exports = router;
And it will change the order of operations:
--->4
Model Type-->SD
Model Type-->SD
Model Type-->SD
Model Type-->SD
Updated Vehicle List:[{"make":"Audi","model":"A3","vin":"QVFCFQT7894563214","modelType":"SD"},{"make":"Audi","model":"A4","vin":"ASECFQT7894563214","modelType":"SD"},{"make":"Audi","model":"Q7","modelType":"SD"},{"make":"Audi","model":"Q5","vin":"QWECFQT7894993214","modelType":"SD"}]
I write a test which firstly has to do post request. I get an error when I run this :
the url is :
http://walla.com:8080/internal/getToken
the code :
function user(){
var postData = {
loginName: 'hello#gmail.com',
password: 'abcdef'
}
var options = {
host: 'http://walla.com',
port: '8080',
path: '/internal/getToken',
body: postData
method: 'POST',
headers: {'Content-Type': 'application/json'}
};
var callback = function(response) {
var str = ''
response.on('data', function (chunk) {
str += chunk;
});
response.on('end', function () {
console.log(str);
});
}
var req = http.request(options, callback);
req.end();
}
describe("ccc", function () {
it("bbbb" , function(){
user();
});
});
Am i doing something wrong?
thanks?
You are missing a comma after the body
var options = {
host: 'http://walla.com',
port: '8080',
path: '/internal/getToken',
body: postData, // Note the Comma at the end
method: 'POST',
headers: {'Content-Type': 'application/json'}
};
Instead, you can directly define the object, like this
var options = {
host: 'http://walla.com',
port: '8080',
path: '/internal/getToken',
body: {
loginName: 'hello#gmail.com',
password: 'abcdef'
},
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
};