Accessing data within object - javascript

app.get('/profile/:id', function(req, res){
var options = { method: 'GET',
url: 'https://api.favoriot.com/v1/streams?max=1',
headers:
{ 'cache-control': 'no-cache',
'content-type': 'application/json',
'apikey': 'api key' } };
request(options, function (error, response, body) {
res.render('profile', {data:body});
console.log(body)
});
});
when I run code above, I get this data:
{"debugCode":null,"statusCode":200,"numFound":1,"results":[{"user_id":"xxx510","stream_created_at":"2019-03-05T16:13:01.982Z","stream_developer_id":"f8b8fcb9-6f3e-4138-8c6b-d0a7e8xxxxx#xxxx510","device_developer_id":"raspberryPIxx#xxx510","data":{"distance":"12.4","status":"1"}}]}
how can I make it only display status only?

AFAIK there is no issue with the code as such. Are you sure that you got the distance and status in the data field of body or is it the intended output? By try using their API playground by setting your API key on it. I have rewritten the code using ES6 standards by promisifying request module or you can use the request-promise-native.
function requestPromisified(options) {
return new Promise(function(resolve, reject) {
request(options, function(error, res, body) {
if (!error && res.statusCode == 200) {
resolve(body);
} else {
reject(error);
}
});
});
}
app.get("/profile/:id", async (req, res) => {
const options = {
method: "GET",
url: "https://api.favoriot.com/v1/streams?max=1",
headers: {
"cache-control": "no-cache",
"content-type": "application/json",
apikey: "api key"
}
};
try {
const body = await requestPromisified(options);
console.log(body);
res.render("profile", { data: body });
} catch (error) {
res.status(400).send('Unable to find a profile')
}
});

1) There is no middleware in this example... you're just making a call to get some data.
2) status is available in body.results[0].data.status so just use that instead of the entire body object

Related

Access the response of Node.JS Post Request

I'm trying the wrap my head around the Client Credentials Flow of Spotify API and in their documentation they have this way to get the Access Token:
var client_id = 'CLIENT_ID';
var client_secret = 'CLIENT_SECRET';
const authOptions = {
url: "https://accounts.spotify.com/api/token",
headers: {
"Authorization":
"Basic " +
new Buffer.from(clientID + ":" + clientSecret).toString("base64"),
"Content-Type": "application/x-www-form-urlencoded",
},
form: {
grant_type: "client_credentials",
},
json: true,
};
request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
var token = body.access_token;
}
});
Now I'm trying to get that token and export or use it in the API calls but whatever I do, I cannot access that statement.
Putting the POST into a variable or function and calling it results in undefined.
This is what I'm trying to achieve:
import authOptions from "./credentials.js";
import pkg from "request";
const { post } = pkg;
const Spotify = {
getAccessToken() {
post(authOptions, function (error, response, body) {
if (!error && response.statusCode === 200) {
const token = body.access_token;
return token;
}
});
},
async search(input) {
const accessToken = Spotify.getAccessToken();
const response = await fetch(
`https://api.spotify.com/v1/search?q=${input}&type=artist`,
{
headers: {
"Authorization": `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
}
);
const data = await response.json();
console.log(data);
},
};
export default Spotify;
Yet of course there's no Access Token returned from that post request.
Is there any way I can convert that piece of code into Async/Await?
You can create a new promise:
async function getAccessToken(){
return new Promise((resolve, reject) => {
post(authOptions, function (error, response, body) {
if(error){
reject(error);
} else if (response.statusCode === 200) {
const token = body.access_token;
resolve(token);
}
});
});
};
The resolve/reject allows you to return that value when the callback is called, and it passes the error to the caller to handle. And you can use this format to promisify any callback-based function, by calling it inside of a promise and using resolve/reject to return the value.

Linkedin api V2 upload a video in node JS

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: ''})
}
});
});
});

How to combine API GET request in nodejs?

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 } ]);

Using the Node Request module with AWS Lambda and API Gateway

This lambda function works:
exports.handler = function(event, context, callback) {
const done = (err, res, func) => callback(null, {
statusCode: '200',
body: res,
headers: { 'Content-Type': 'application/json' },
})
done(null, 'works'))
}
I can hit the API Gateway end point and receive the response message, 'works'.
However, when I add a request call (POSTing a message to Slack) that looks like this:
const request = require('request')
const moment = require('moment-timezone')
exports.handler = function(event, context, callback) {
// the json object is built following these docs:
// https://api.slack.com/docs/message-attachments
const SLACK_WEB_HOOK_URL = process.env.SLACK_WEB_HOOK_URL
const uri = SLACK_WEB_HOOK_URL
const method = 'POST'
const options = {
json,
uri,
method,
}
const slack = (opts) => {
request.post(opts, (err, response, body) => {
if (response.statusCode < 300) {
return 'Success!'
} else {
return 'Err!'
}
})
}
const done = (err, res, func) => callback(null, {
statusCode: '200',
body: res,
headers: { 'Content-Type': 'application/json' },
})
done(null, slack(options))
}
The server hangs when I hit the API end point ...
And I get a Task timed out after 10.00 seconds error:
{
"errorMessage": "2017-06-23T16:41:21.483Z c385e32e-5832-11e7-8c4f-673b524cf783 Task timed out after 10.00 seconds"
}
But my Slack POST request gets sent and I see the message in the channel.
How do I send the POST request and then wait for it to return, and then exit the lambda function with a custom response message?
Thanks for the help!
Put the callback into the callback of the post method
request.post(opts, (err, response, body) => {
if (response.statusCode < 300) {
return callback(null, {
statusCode: '200',
body: res,
headers: { 'Content-Type': 'application/json' },
});
} else {
return callback(err);
}
});

Nodejs Cannot get response.body's variables

I can access the body of the response but I cannot access the body.success
userInfo:function (req,res) {
var users = [];
db.Users.find({},function (err,result) {
result.forEach(function (user) {
users.push(user);
});
res.json({success:true, userList:users});
});
}
info:function (req,res) {
var options = { method: 'GET',
url: config.auth_url + '/info',
headers:
{
'cache-control': 'no-cache'
},
form:
{}
};
request(options, function (error, response, body) {
if (error)
throw new Error(error);
else if (body.success)
res.json(response.body);
else
res.json({success: false, code: 404});
});
}
This is the response.body
{"success":true,"userList":["5895ea3849616b05d89e27ce","58989c0abe93e41816b91eaf","5899e9bfadf35729818b52b7"]}
Is anyone have idea that I can return appropriate json date because I think that its not a valid json so that it give error.
For the Error :
response.body.success = undefined;
JSON.parse(body) will solve your problem as needed.

Categories