I am calling an api to monitor the state of the response. I have to keep calling api until the response state is successfull. I am calling
I am calling getHeader function from another js file to get the response from API get call. I have to keep calling api again and again until the result.success is successfull. However when the state is changed to successfull, the function stop and doesn't return resolve. I think everytime i call function a new promise is created and it is not able to return resolve.
Can someone help me on this.
*import Promise from 'bluebird'
var requestPromise = Promise.promisifyAll(require('request'))
var instance;
const MonitorResponse = class {
constructor() {
if (instance) {
return instance;
}
instance = this;
}
/**
*
*/
getHeader(authToken,statusHeader) {
console.log(" Successeded Get Geader " + statusHeader + " " +authToken );
return new Promise(function (resolve, reject) {
var self=this;
var options = {
method: 'GET',
rejectUnauthorized: false,
strictSSL: false,
url: statusHeader,
headers: {
'Authorization': 'Bearer ' + authToken,
},
json:true
};
requestPromise.getAsync(options)
.then(function (headerResponse) {
console.log("Response Get Header " + JSON.stringify(headerResponse));
var state = headerResponse.body.state;
console.log("Response Get Header state " +state );
if(state=="SUCCESSFUL")
{
return resolve(" from loop ");
}
else{
self.getHeader(authToken,statusHeader);
console.log(" After recursion state " +state );
}
})
.catch(function (error) {
return reject(error)
});
}.bind(this));
}
}
module.exports = MonitorResponse*
Expected Result is to get return resolve(" from loop "); when getHeader function is called.
Related
I have using azcapture api which only accepts number as id at the end of 'path' Options of Fetch/Request api and works when I type in the id e.g.
Var options = {
'path':'url+key+1234455
}
When 1234455 is typed like above it works. But since this is the resp I cannot beforehand know the id so I pass it from the req result which was a POST and now I do a GET, effectively I have chained them without using Promises:
Function secondCall(id)
Console.log (id)
Var options = { 'path': url+key+id
}
This above always fails even if I parse id with parseInt or Number () or if I parse or coerce then
id.toString()
since ClientRequestArgs.path is a string (ClientRequestArgs.path?: string), I believe, it always resolves to a string.
Am I seeing double here or is there a fundamental issue?
POSTMAN works fine btw and the code I have below is exported from POSTMAN except in chainResolve function the first 4 lines are my conversion code.
If I change this line and replace the resolvedID to a pre generated id it will work:
url: 'http://azcaptcha.com/res.php?key=kowg1cjodmtlyiyqheuzjfzta4ki0vwn&action=get&id=335439890',
But as resolvedID the converted string (pre generated id) into an int it won't work.
Full code with keys omitted:
var request = require('request');
var fs = require('fs');
var http = require('follow-redirects').http;
var axios = require('axios');
var options = {
'method': 'POST',
'url': 'http://azcaptcha.com/in.php?key=key&method=post',
'headers': {
},
formData: {
'file': {
'value': fs.createReadStream('C:/Users/jsonX/Documents/fiverr/captchatest.png'),
'options': {
'filename': 'C:/Users/jsonX/Documents/fiverr/captchatest.png',
'contentType': null
}
}
}
};
//let respondedID;
convertToInt = (x) => {
var converted=parseInt(x[1], 10);
return converted;
}
request(options, function (error, response) {
if (error) throw new Error(error);
var respondedID = response.body;
console.log('line 26 '+respondedID);
chainResolve(respondedID);
});
chainResolve = (id) => {
var sid = id.split('|');
var resolvedID=parseInt(sid[1], 10)
console.log(parseInt(sid[1], 10));
console.log('line 40 '+convertToInt(sid));
var config = {
method: 'get',
url: 'http://azcaptcha.com/res.php?key=key&action=get&id=resolvedID',
headers: { }
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
}
Solved it! It turns out this API will not give you back any result if the resp is CAPTCHA_NOT_READY. So the solution was to set a timeout and push this with a callback in my response block of the second request:
axios(config)
.then(function (response) {
if (result === 'CAPCHA_NOT_READY'){
console.log('Captcha is being processed');
var startTime = setTimeout(function() {
waitR(id);
clearTimeout(startTime);
},5000);
} else {
console.log(result.split('|')[1]);
}
})
.catch(function (error) {
console.log(error);
});
waitR = (id) => {
console.log('The result is being processed ...');
chainResolve(id);
}
I have an issue with Async function with post request. I don't success to sendback a string value.
Here is the code
exports.GetQuote = async (req, res, next) => {
try{
var dim = req.body.dimension;
test = new sreq({ ** A LOT OF DATA ** })
const data = JSON.stringify(test);
request.post({
headers: { 'content-type': 'application/json' },
url: 'https://www.xxxx.com/API',
body: data
}, (error, res, body) => {
if (error) {
console.error(error)
console.log('ERROR REQUEST');
return
}
datares = JSON.parse(body);
console.log(datares.value+" "+datares.Code); ***VALUE IS OK***
response = datares.value+" "+datares.Code;
return response; *** NOT RETURN VALUE ***
});
}catch (e){
console.error(e);
}
}
the console.log is correct in nodejs console, but it dont't return the value ?
Have i missed something?
Thanks for Help
You are not catching the return value. You could define a variable outside the callback function.
exports.GetQuote = async (req, res, next) => {
try{
let response;
var dim = req.body.dimension;
test = new sreq({ ** A LOT OF DATA ** })
const data = JSON.stringify(test);
request.post({
headers: { 'content-type': 'application/json' },
url: 'https://www.xxxx.com/API',
body: data
}, (error, res, body) => {
if (error) {
console.error(error)
console.log('ERROR REQUEST');
return
}
datares = JSON.parse(body);
console.log(datares.value+" "+datares.Code); ***VALUE IS OK***
response = datares.value+" "+datares.Code; // sets to the response var we defined above
});
}catch (e){
console.error(e);
}
return response; // Return here
}
With an async function you pause the execution of the code so you don't have the need for a callback. Like with a phone, either you tell the other person to call you back or you await his return to the phone after he done his task you set him.
So for an async function the code can look something like that.
exports.GetQuote = async (req, res, next) => {
try {
// dim variable not used -- > delete
var dim = req.body.dimension;
test = new sreq({ /** A LOT OF DATA **/ })
const data = JSON.stringify(test);
// code stops running until response is here
let response = await request.post({
headers: { 'content-type': 'application/json' },
url: 'https://www.xxxx.com/API',
body: data
})
// error handling I can't say
// since I don't know what is returned here if the call should fail
if(response){
datares = JSON.parse(response.body);
console.log(datares.value + " " + datares.Code); /*** VALUE IS OK ***/
response = datares.value + " " + datares.Code; // sets to the response var we defined above
return response; // Return here
} else{
throw new Error({msg: `something went wrong`})
}
} catch (e) {
console.error(e);
}
}
Do be aware that exports.GetQuote now hold a Promise that is implicitly returned by an async function
I am trying to save my response into the database. but it shows only the console and does not return the write to the database.
here is my code....
exports.saveGroups = functions.firestore.document("Users/{user_id}").onWrite((change,context) => {
token_id1 = change.after.data().token_id;
token_email = change.after.data().email;
image = change.after.data().image;
name1 = change.after.data().name;
user_id = context.params.user_id;
console.log('token_id1:' + token_id1);
console.log('token_email:' + token_email);
console.log('Image:' + image);
console.log('name:' + name1);
console.log('user_id' + user_id);
var headers = {
'Authorization': 'key = AAAATmJbwHE:APA91bGIEsq0aioIzAa_7g5JvLX1NPU3z1Gkt6vxB2J-I_9IvllwDJaxjmEp5DPw6ZoEBmXfwiYwICrMuE0kQrvxuHTGPc5YKr3i-JNru-o6AHnrAjq4r7iZWmzUuSmPwu8CbR2kXEIq',
'project_id': '336657629297',
'Content-Type': 'application/json'
}
var options = {
url: 'https://android.googleapis.com/gcm/notification',
method: 'POST',
headers: headers,
json: {'operation': 'create',
'notification_key_name': token_email,
'registration_ids': [token_id1]}
}
const promise = request(options, function (error, response, body) {
tokenName = body.notification_key;
console.log('Key: ' + tokenName); //here it shows me the correct value
return db.collection('Users').doc(user_id).set({name: name1,token_id: token_id1,notification_key: tokenName,image: image,email: token_email}).then(() => { //never reach this line
return console.log("Document successfully written!"); //never returns this console
}).catch(function(error) {
return console.error("Error writing document: ", error);
});
})
return promise; //finishes with status "ok"
});
I've gone through the promises documentation. but I don't find any example to handle the "request" functions.
requires help. thanks in advance.
request supports callback interfaces natively but does not return a promise, which is what you must do within a Cloud Function.
I strongly suggest that you watch these videos from the Firebase team: https://www.youtube.com/watch?v=7IkUgCLr5oA&t=28s and https://www.youtube.com/watch?v=652XeeKNHSk which explain this key concept.
You could use request-promise (https://github.com/request/request-promise) and rp(...) method which "returns a regular Promises/A+ compliant promise" and then do something like:
....
return rp(options) // <- You should return this promise within the Function
.then(function (body) {
const tokenName = body.notification_key;
console.log('Key: ' + tokenName);
return db.collection('Users').doc(user_id).set({name: name1,token_id: token_id1,notification_key: tokenName,image: image,email: token_email});
})
.catch(function (err) {
console.log(err);
});
I use NodeJS and request lib to make some request to an API.
I understand now that all requests are async and so it doesn't "wait" the result of the GET call, so the index of my Loop is always the same.
I was wondering if there was any simple way (without any lib) to wait for the response of the request call ?
For now, my code is this :
for (var i in entries) {
var entryId = entries[i]['id'];
var options = {
url: 'https://api.com/'+ entryId +'/get/status',
method: 'GET',
headers: {
'Authorization': auth
}
};
console.log(' ENTRY ID > '+ entryId);
request(options, function(error, response, body) {
var response = JSON.parse(body);
if (response.status.code == 200) {
var id = response.status.id;
var data = [];
data['id'] = id;
data = JSON.stringify(data);
// show first entryId of loop
console.log(' > MY ID : '+ id + ' - '+ entryId);
options = {
host: hostname,
port: 80,
path: '/path/function2',
method: 'PUT'
};
var post = http.request(options, function(json) {
var body = '';
json.on('data', function(d) {
body += d;
});
json.on('end', function() {
console.log('> DONE');
});
}).on('error', function(e) {
console.log(e);
});
post.write(data);
post.end();
}
});
}
You are looking for async/await.
Wrap your logic inside an async function, then you can await for the promise to resolve.
const request = require('request-promise')
async function foo (a) {
for (i in a)
try {
let a = await request('localhost:8080/')
// a contains your response data.
} catch (e) {
console.error(e)
}
}
foo([/*data*/])
Just use the promisified version of request module.
You also can use Promises to wait for your async code to finish.
function asyncCode(msg, cb){
setTimeout(function() {cb(msg);}, 1000);
}
var p1 = new Promises(function(resolve){
asyncCode("my asyncCode is running", resolve);
});
p1.then(function(msg) {
console.log(msg);
}).then(function() {
console.log("Hey I'm next");
});
console.log("SyncCode, Async code are waiting until I'm finished");
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.