How can i use promise method in node - node.js

I was trying out the promise function for the REST API instead of using axios method. so I can wait for the result and if there is any error. can anyone help me change this code to promise in node.js so I can do a fetch using promise method. thank you
this is my code
const email = "xxx#xxxx.com"
function isUserExists(email, kc_accessToken) {
let url = `${path}/users?email=${email}`;
return axios_instance.get(url,
{
headers: {
"content-type": "application/json",
"authorization": `Bearer ${kc_accessToken}`
}
}).then(function (response) {
if (response.data.length > 0) {
return true;
} else {
return false;
}
})
.catch(function (error) {
console.log("some error occured");
});
}
Method call
http.createServer(function Test() {
getAccessToken().then(function (response) {
kc_accessToken = response.data.access_token;
IsUserExists(email, kc_accessToken).then((resp) => {
console.log(resp)
if(resp) {
console.log("Do Not Create")
} else if (!resp) {
console.log("Creat a new User")
}
})
}).catch(function (error) {
// handle error
console.log(error);
})
.then(function () {
// always executed
});;
}).listen(8081);

I think you need something like that :
const email = "xxx#xxxx.com"
const request = require('request');
function isUserExists(email, kc_accessToken) {
let url = `${path}/users?email=${email}`;
return new Promise(function(resolve, reject){
request({
url: url,
headers: {
"content-type": "application/json",
"authorization": `Bearer ${kc_accessToken}`
}
}, function (error, response, body) {
if (error) {
console.log("some error occured");
}
if (response.data.length > 0) {
return resolve();
}
return reject();
});
});
}

Related

How to return a value from axios outside axios function

I have a router.get which calls another function, like this:
router.get("/", (req, res) => {
const data = especiaisTest.getEspeciais();
console.log(data);
});
The function which is calling is this one:
function getEspeciais() {
db.query(async (tokenResponse) => {
try {
const response = await axios.get(URL, {
headers: {
Authorization: `Bearer ${tokenResponse.accessToken}`,
},
});
return response.data;
} catch (error) {
console.error(error);
}
});
}
Whenever i call it, I just get console.logged an undefined.
I tried returning a value outside the db.query function, for example:
function getEspeciais() {
db.query(async (tokenResponse) => {
try {
const response = await axios.get(URL, {
headers: {
Authorization: `Bearer ${tokenResponse.accessToken}`,
},
});
return response.data;
} catch (error) {
console.error(error);
}
});
return 'hello'
}
And it will display the 'hello' in the console. How can I get the response.data out of the db.query in order to be able to show the data?
Question codes.
router.get("/", (req, res) => {
const data = especiaisTest.getEspeciais();
console.log(data);
});
function getEspeciais() {
db.query(async (tokenResponse) => {
try {
const response = await axios.get(URL, {
headers: {
Authorization: `Bearer ${tokenResponse.accessToken}`,
},
});
return response.data;
} catch (error) {
console.error(error);
}
});
}
Should be:
router.get("/", async (req, res) => {
const data = await especiaisTest.getEspeciais();
async function getEspeciais() {
return db.query(async (tokenResponse) => {
Then you will see something else rather than undefined.
If return undefined, the db.query method return nothing.

Request Promise unhandled reject

Basically I have to do a POST request an try to save this data on an API after I get the return of this POST and save this information on a database.
So, I did a call to a promise (saveProcessedData or saveErrorData) inside another promise, works as expected although is trowing out a warning:
Unhandled rejection StatusCodeError: 400
const sendData = async(data, item) => {
let payload = [],
dataProcessed = [];
let options = {
method: data.endpoint.method,
url: api._url + data.endpoint.url,
headers:
{
'Postman-Token': api._postmanToken,
'cache-control': api._cache,
'x-ccasset-language': 'en',
Authorization: data.token
},
body: item,
json: true
};
return new Promise((resolve, reject) => {
api._request(options, async (error, response, body) => {
if(!response.body.errorCode && response.statusCode === 200) {
payload = {
body: response.body,
type: data.req.body.type
}
dataProcessed = await db.saveProcessedData(payload);
} else {
payload = {
body: item,
type: data.req.body.type,
description: response.body.message
}
dataProcessed = await db.saveErrorData(payload);
}
if (error) {
reject(error)
}
resolve(dataProcessed);
});
});
}
How Can I catch this error?
It's better if you don't mix callbacks & promises the way you're doing it. You're getting that error because you're not handling the errors correctly inside api._request callback.
Wrap your code inside the callback in a try/catch, because that's how you handle exceptions in async functions.
new Promise(async resolve => {
await Promise.reject() // Unhandled Promise Rejection
}).catch(console.error) // not catched
Should be:
new Promise(async resolve => {
try {
await Promise.reject()
resolve();
} catch(e) {
reject(e)
}
}).catch(console.error) // catched
In any case, since you're wrapping api._request in a Promise, it would be better to do:
const sendData = async(data, item) => {
// ...
const { error, response, body } = await new Promise((resolve, reject) => {
api._request(options, (error, response, body) => resolve({ error, response, body }))
})
if(!response.body.errorCode && response.statusCode === 200) {
payload = {
body: response.body,
type: data.req.body.type
}
dataProcessed = await db.saveProcessedData(payload);
} else {
payload = {
body: item,
type: data.req.body.type,
description: response.body.message
}
dataProcessed = await db.saveErrorData(payload);
}
return dataProcessed;
}
And attach a .catch handler to .sendData
Aside from that in your code, if error is truthy, you're rejecting and then resolving, nothing wrong will happen in that case, but it's better to use return reject(). A Promise, can't be rejected & resolved.
if (error) {
return reject(error)
}
resolve(dataProcessed);
If you're using request, you can use request-promise or request-promise-native which are Promise wrappers around request package.
Just formatting
const sendData = async (data, item) => {
const options = {
method: data.endpoint.method,
url: api._url + data.endpoint.url,
headers: {
'Postman-Token': api._postmanToken,
'cache-control': api._cache,
'x-ccasset-language': 'en',
Authorization: data.token
},
body: item,
json: true
};
return Promise.resolve()
.then(() =>
new Promise((resolve, reject) => {
api._request(options, (error, response) => {
if (!response.body.errorCode && response.statusCode === 200) {
return resolve(
{
body: response.body,
type: data.req.body.type
}
);
}
return reject({
body: item,
type: data.req.body.type,
description: error || response.body.message
});
})
}))
.then(payload => db.saveProcessedData(payload))
.catch(payload => db.saveErrorData(payload))
}
When you call sendData() you can use Promise.prototype.catch() to catch exceptions that occurred in your promise, including any reject():
sendData(myData, myItem)
.then(result => {
//do stuff with result
}
.catch(error => {
//handle error
};

how to get data outside request

I have a scenario where i need to take response (body) of request method outside request. How can i do it?
request.post({
url: 'http://localhost/api/messages',
form: { key: message }
}, function (err, httpResponse, body) {
tmsg = body;
})
console.log(tmsg);
I need this tmsg outside for next processing, Actual scenario is as below.
app.post('/incomemsg', function (req, res) {
var mediaCount = req.body.NumMedia;
if (mediaCount == 0) {
//var twiml = getResponse(message);
var twiml = new MessagingResponse();
request.post({
url: 'http://localhost:3978/api/messages',
form: { key: message }
}, function (err, httpResponse, body) {
tmsg = body;
})
console.log(tmsg);
}else {
//dosomething which outputs tmsg
}
res.writeHead(200, { 'Content-Type': 'text/xml' });
res.end(tmsg.toString());
});
The problem is you are trying to assign value to a global variable in request.post's callback() which is only called after request.post is executed by Asynchronous logic(API calls are all async), so a better way would be to promisify request.post and await the request.post to make it seem synchronous.
const requestPromisified = requestObject =>
new Promise((resolve, reject) => {
request.post(requestObject, function(err, httpResponse, body) {
if (err) {
reject(err);
}
resolve(body);
});
});
const body = await requestPromisified({
method: "POST",
url: "http://localhost/api/messages",
form: { key: message }
});
You only can do something with tmsg when you made the request so you need to rearrange your code like this:
app.post('/incomemsg', function (req, res) {
var mediaCount = req.body.NumMedia;
var twiml = new MessagingResponse();
request.post({
url: 'http://localhost:3978/api/messages',
form: { key: message }
}, function (err, httpResponse, body) {
tmsg = body;
console.log(tmsg);
if (mediaCount === 0) {
//do something with tmsg
} else {
//do something else with tmsg
}
res.writeHead(200, { 'Content-Type': 'text/xml' });
res.end(tmsg.toString());
});
});
Otherwise tmsg will be null because there was no request made to fill that variable.

NodeJS function returns before intended

I have a function that loops and makes some API calls:
sendText(clientArr){
clientArr.forEach(function (textObject, index) {
var myRequest = {
body: textObject.messageContent,
to: { phoneNumber: textObject.phoneNumber },
rules: ['sms']
};
var options = {
method: 'POST',
url: comapiUrl,
headers:
{
'cache-control': 'no-cache',
'content-type': 'application/json',
'accept': 'application/json',
authorization: 'Bearer ' + yourComapiAccessToken
},
body: myRequest,
json: true
};
console.log('');
console.log('Calling Comapi...');
request(options, function (error, response, body) {
if (error) throw new Error(error);
console.log("HTTP status code returned: " + response.statusCode);
// Check status
if (response.statusCode == 201)
{
// All ok
console.log('SMS message successfully sent via Comapi "One" API');
}
else
{
// Something went wrong
console.log('Something went wrong!');
}
console.log(body);
return response
});
})
};
This function got called from here:
function callAPI(req, res, apiMethod) {
let params = {};
params = req.params;
params.headers = req.headers;
if (req.method.toLowerCase() != 'get') {
params.post = req.body;
}
params.query = req.query;
params.middlewareStorage = req.middlewareStorage;
apiMethod(params)
.success(function (result) {
res.send(result);
})
.failure(function (error) {
console.logger.error(error);
if (!(Object.prototype.toString.call(error) === '[object Object]')) {
error = {success: false, error: error};
}
console.logger.error(error);
res.status(500).send(error);
});
}
router:
router.post('/sendText', function (req,res) {
callAPI(req, res, fn.bind(apiObj, 'sendText'));
});
What I am getting in response is:
POST /clients/sendText 500 320.615 ms - 1514
2018-01-04 02:03:38.887 DEBUG app - HTTP status code returned: 201
It returns with 500 error:
Cannot read property 'success' of undefined\n at callAPI (
before I intended it to return.
How do I fix this?
The sendText method is returning nothing and thus undefined. And hence that does not have success or failure method. However, even if it returns a valid response. The response should have success and failure method.
A better way here will to use promises. You can return promise from api method and change the callAPI method to use the promise interface.
sendText method (using request-promise instead of request)
sendText(clientArr) {
return Promise.all(clientArr.map(function (textObject, index) {
var myRequest = {
body: textObject.messageContent,
to: { phoneNumber: textObject.phoneNumber },
rules: ['sms']
};
var options = {
method: 'POST',
url: comapiUrl,
headers:
{
'cache-control': 'no-cache',
'content-type': 'application/json',
'accept': 'application/json',
authorization: 'Bearer ' + yourComapiAccessToken
},
body: myRequest,
json: true,
resolveWithFullResponse: true
};
console.log('');
console.log('Calling Comapi...');
return request(options)
.then(function (response) {
if (error) throw new Error(error);
console.log("HTTP status code returned: " + response.statusCode);
// Check status
if (response.statusCode == 201)
{
// All ok
console.log('SMS message successfully sent via Comapi "One" API');
}
else
{
// Something went wrong
console.log('Something went wrong!');
}
console.log(body);
return response
});
})
};
callApi
function callAPI(req, res, apiMethod) {
let params = {};
params = req.params;
params.headers = req.headers;
if (req.method.toLowerCase() != 'get') {
params.post = req.body;
}
params.query = req.query;
params.middlewareStorage = req.middlewareStorage;
apiMethod(params)
.then(function (result) {
res.send(result);
})
.catch(function (error) {
console.logger.error(error);
if (!(Object.prototype.toString.call(error) === '[object Object]')) {
error = {success: false, error: error};
}
console.logger.error(error);
res.status(500).send(error);
});
}

api call to sinch as promise

I've tested the interface and made some changes to use with my sailsjs (version 11) on the backend. In this case I use a sails service and things seem fine but I always get back a pending status.
```
SinchService.js
var sinchAuth = require('sinch-auth');
var request = require('request');
var sinchMessaging = {};
var Promise = require('bluebird');
//sinchMessaging.sendMessage = function (phoneNumber, message) {
//exports.sendMessage = function (phoneNumber, message) {
module.exports = {
sendMessage: function (phoneNumber, message) {
var auth = sinchAuth();
if (!auth) {
throw new Error("No Authorization was provided");
}
var options = {
method: 'POST',
url: "https://messagingApi.sinch.com/v1/sms/" + phoneNumber,
headers: {
"Content-Type": "application/json",
"Authorization": auth
},
body: "{\"Message\":\"" + message + "\"}"
// body: {"Message" : message }
};
return new Promise(function (resolve, reject) {
request(options, function (error, response, body) {
sails.log("Finished with call");
if (error) {
sails.log(error);
throw error;
}
else {
sails.log("Finished with body ", body);//.MessageId
return resolve(response.body);
}
});
})
},
getStatus: function (messageId) {
var auth = sinchAuth();
if (!auth) {
throw new Error("No Authorization was provided");
}
var options = {
method: 'GET',
url: "https://messagingApi.sinch.com/v1/sms/" + messageId,
headers: {
"Content-Type": "application/json",
"Authorization": auth
}
};
return new Promise(function (resolve, reject) {
request(options, function (error, response, body) {
sails.log("Finished with call");
if (error) {
sails.log(error);
throw error;
}
else {
return resolve(response.body);
}
});
})
}
};
```
agendaService.js
var jsonObjS;
SinchService.sendMessage(phoneNumber, message).then(function (results) {
var jsonObj = JSON.parse(results);
console.log('results sendMessage ', jsonObj.messageId);
if (jsonObj.messageId!==undefined){
SinchService.getStatus(jsonObj.messageId).then(function (results_s) {
jsonObjS = JSON.parse(results_s);
console.log('results getStatusS ', jsonObjS.status);
SinchService.getStatus(jsonObjS.messageId).then(function (results_s) {
var jsonObjS = JSON.parse(results_s);
console.log('results getStatusS ', jsonObjS.status);
});
});
```
Pending will always be the first status, query again after some time to see the status of of the message.

Resources