In my node.js api I am trying to pass multiple values into the fields tracking and carrier , but I have been unsuccessful. I am able to do this with single values (1 tracking number for tracking and 1 carrier code for carrier), but not for multiple values. I feel like there should be a loop involve, but maybe I am incorrect in stating this. Any help would be greatly appreciated.
Index.html
<script>
function UserParams() {
console.log('UserParams')
var trackingNumber = ['123', '456'];
var carrierCode = ['usps', 'fedex'];
var url = '/api/tracking/retrieve/';
$.ajax({
type: 'GET',
url: url,
data: { tracking: trackingNumber, carrier: carrierCode },
dataType: 'json',
error: function (e) {
console.log('Error Message: ', e.message);
}
});
}
</script>
Controller.js
app.get("/api/tracking/retrieve", (req, res) => {
var carrier = req.query.carrier;
var tracking = req.query.tracking;
console.log('carrier array', carrier);
console.log('tracking array', tracking);
var options = {
method: "GET",
url: 'https://api.example.com/v1/tracking',
qs: { carrier_code: carrier, tracking_number: tracking },
headers:
{
'api-key': process.env.SECRET_KEY_SE,
'accept': 'application/json'
}
}
console.log("Url: ", req.url);
console.log("Query: ", req.query);
res.send("ok");
request(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log('BODY', body)
var trackingData = JSON.parse(body)
table = 'tracking_table';
col = [
'user_id',
'tracking_number',
'carrier_code',
];
val = [
user_id,
trackingData.tracking_number,
options.qs.carrier_code,
];
main.create(table, col, val, function (data) {
res.json({
id: data.insertId,
user_id: user_id,
tracking_number: data.tracking_number,
carrier_code: data.carrier_code,
});
})
}
})
})
Result in terminal:
carrier array [ 'usps', 'fedex' ]
tracking array [ '123', '456' ]
Url: /api/tracking/retrieve/?tracking%5B%5D=123&tracking%5B%5D=456&carrier%5B%5D=usps&carrier%5B%5D=fedex
Query: { tracking: [ '123', '456' ],
carrier: [ 'usps', 'fedex' ] }
Edit: Edited question to include further context.
Depending on what the backend is you can try simply using arrays for this purpose, e.g.
var tracking = ['9361289691090998780245','784644233438'];
var carrier = ['usps','fedex'];
options = {
method: "GET",
url: 'https://api.example.com/v1/tracking',
qs: { tracking_number: tracking, carrier_code: carrier },
headers:
{
'api-key': process.env.SECRET_KEY_SE,
'accept': 'application/json'
}
}
request(options, function (error, response, body) {
if (error) console.error("An error occurred: ", error);
console.log("body: ", body);
});
If this is served by Express, the query string will be parsed correctly, e.g.
app.get("/api/tracking/retrieve", (req, res) => {
console.log("Url: ", req.url);
console.log("Query: ", req.query);
res.send("ok");
});
This is what would be logged by Express;
Url: /api/tracking/retrieve?tracking_number%5B0%5D=9361289691090998780245&tracking_number%5B1%5D=784644233438&carrier_code%5B0%5D=usps&carrier_code%5B1%5D=fedex
Query: { tracking_number: [ '9361289691090998780245', '784644233438' ], carrier_code: [ 'usps', 'fedex' ] }
Of course it depends on the API provider, so it might be worth seeing if they have documentation on how parameters should be formatted.
Try to change string tracking & carrier to array with function split
app.get('/api/tracking/retrieve', function (req, res) {
options = {
method: "GET",
url: 'https://api.example.com/v1/tracking',
qs: { tracking_number: tracking.split(','), carrier_code: carrier.split(',') },
headers:
{
'api-key': process.env.SECRET_KEY_SE,
'accept': 'application/json'
}
}
request(options, function (error, response, body) {
})
});
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 have this function below that is supposed to fetch data from a Twitch API Endpoint,
But I need to pass a query parameter with a key to_id and a value, and I don't know how to pass query parameters using this npm module,
I think I have to do this in the gameOptions object below,
(Here's a link of the doc: https://www.npmjs.com/package/request#requestoptions-callback)
function gameRequest(accessToken) {
setTimeout(() => {
const gameOptions = {
url: "https://api.twitch.tv/helix/users/follows",
method: "GET",
headers: {
"Client-ID": MY_CLIENT_ID,
Authorization: "Bearer " + accessToken,
},
};
if (!accessToken) {
console.log("No Token");
} else {
console.log(gameOptions);
const gameRequest = request.get(gameOptions, (err, res, body) => {
if (err) {
return console.log(err);
}
console.log(JSON.parse(body));
});
}
}, 2000);
}
You can user qs in gameOptions :
const gameOptions = {
url: "https://api.twitch.tv/helix/users/follows",
method: "GET",
qs : {
"to_id" : valueToPass
},
headers: {
"Client-ID": MY_CLIENT_ID,
Authorization: "Bearer " + accessToken,
},
};
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();
I'm looking for uploading in node JS a video throught the linkedin API V2 , butI'm still receiving a status code 403. I correctly followed the steps in the documentation. (https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/vector-asset-api#register-an-upload-for-video)
let req = request(`https://assets.mixkit.co/videos/2125/2125-720.mp4`)
.pipe(fs.createWriteStream('video.mp4'));
req.on('close', ()=>{
request({
url: uploadUrl,
method: 'POST',
headers: {
"x-amz-server-side-encryption-aws-kms-key-id": "MY_ID",
"x-amz-server-side-encryption": "aws:kms",
"Content-Type": "application/octet-stream"
},
encoding: null,
body: fs.createReadStream('video.mp4')
}, (error, response, body) => {
if (error) {
cb(error)
} else {
cb({response: response, body: body, url: uploadUrl,})
}
});
});
It's working when using the CURL command https://learn.microsoft.com/en-us/linkedin/marketing/integrations/community-management/shares/vector-asset-api#upload-the-video . , but I need to do it in node js.
Any help is greatly appreciated :)
finally I found the solution :)
Working code
let req = request(`https://assets.mixkit.co/videos/2125/2125-720.mp4`)
.pipe(fs.createWriteStream('video.mp4'));
req.on('close', ()=>{
fs.readFile('video.mp4', function(err, data) {
if (err) throw err;
var encodedImage = new Buffer(data)
request({
url: url,
method: 'PUT',
headers: {
"x-amz-server-side-encryption-aws-kms-key-id": "MY_ID",
"x-amz-server-side-encryption": "aws:kms",
"Content-Type": "application/octet-stream"
},
encoding: null,
body: encodedImage
}, (error, response, body) => {
if (error) {
cb(error)
} else {
cb({response: response, body: body, url: url, access_token: access_token, data: ''})
}
});
});
});
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 } ]);