When i run code given below in terminal than i get following error:-
ReferenceError: resolve is not defined.
const request = require('request');
let geoLocationPromise = (zipCode) => {
return new Promise(()=>{
request({
url:`https://maps.google.com/maps/api/geocode/json?address=${zipCode}`,
JSON: true
}, (error, response, body)=>{
if(error){
reject('Unable to connect to server');
}else if (response.statusCode === 200) {
console.log(body);
resolve(JSON.parse(body.currently, undefined, 2));
}
});
});
};
geoLocationPromise(841101).then((loc)=>{
console.log(loc);
}, (errorMessage)=>{
console.log(errorMessage);
});
You need to declare the parameters “reject” and “resolve” for your Promise's callback, like this:
const request = require('request');
let geoLocationPromise = (zipCode) => {
return new Promise((resolve, reject)=>{
request({
url:`https://maps.google.com/maps/api/geocode/json?address=${zipCode}`,
JSON: true
}, (error, response, body)=>{
if(error){
reject('Unable to connect to server');
}else if (response.statusCode === 200) {
console.log(body);
resolve(JSON.parse(body.currently, undefined, 2));
}
});
});
};
Related
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 3 years ago.
In that code, console.log(game) gives me an array, but return(game) gives me null.
I don't know, what should I do to gain that array
takeApi: async (root, args, { req }, info) =>{
let userNick='Izyi';
var request = require('request');
var JsonFind=require('json-find');
var url = 'https://someapi/'+userNick;
var game;
request.get({
url: url,
json: true,
headers: {'API-KEY': 'XXX'}
}, (err, res, data) => {
if (err) {
console.log('Error:', err);
} else if (res.statusCode !== 200) {
console.log('Status:', res.statusCode);
} else {
const doc= JsonFind(data.lifeTimeStats);
var matchesPlayed=(doc.checkKey('7').value);
var wins=(doc.checkKey('8').value);
var kills=(doc.checkKey('10').value);
game ={kills:kills,wins:wins,matchesPlayed:matchesPlayed}
console.log(game);
return(game);
}
})
return(game);
}
request.get works via a callback and is not directly compatible with async/await. That callback happens when the request is done or has errored out. The return(game); then happens before the request has completed.
You need to return a new Promise and then resovle or reject based on the results passed to the callback.
You can then await or .then takeApi and expect to have a value returned.
const takeApi = async(root, args, { req }, info) => {
let userNick = 'Izyi';
var request = require('request');
var JsonFind = require('json-find');
var url = 'https://someapi/' + userNick;
// return a Promise, which will work
// by the called using `await` or `.then`
return new Promise((resolve, reject) => {
request.get({
url: url,
json: true,
headers: {
'API-KEY': 'XXX'
}
}, (err, res, data) => {
if (err) {
console.log('Error:', err);
// error, reject
reject(err);
} else if (res.statusCode !== 200) {
console.log('Status:', res.statusCode);
// error, reject
reject(res.statusCode);
} else {
const doc = JsonFind(data.lifeTimeStats);
var matchesPlayed = (doc.checkKey('7').value);
var wins = (doc.checkKey('8').value);
var kills = (doc.checkKey('10').value);
const game = {
kills: kills,
wins: wins,
matchesPlayed: matchesPlayed
}
console.log(game);
// success, resolve
resolve(game);
}
})
});
}
I am playing with ASK SDK v2 provided by Amazon in order to make Skill for Alexa but I face an architectural problem :
First of all, the HTTP request works like a charm but I would like to return speach response if and only if my HTTP request is complete but I don't even know if it's possible because of the "handle" function that should return something (look at comments) :
const MyIntentHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest' || (request.type === 'IntentRequest' && request.intent.name === 'MyIntent');
},
handle(handlerInput) {
var options = {
host: 'http://foo.com',
port: 80,
path: '/mypath',
method: 'GET'
};
var req = http.request(options, function(result){
result.on("end", function(){
//I would like to return speak here like that :
//return handlerInput.responseBuilder.speak("It works").withSimpleCard("MyTestApp", "It works").getResponse()
})
});
req.end();
//And I would like to remove this line to manage response in result.on("end", function(){}) above
return handlerInput.responseBuilder.speak("It works").withSimpleCard("MyTestApp", "It works").getResponse();
},
};
Any idea to deal with this ?
I found the official way to make it :
1) Create a new funtion that manage http request and return a promise :
function httpGet(options) {
return new Promise(((resolve, reject) => {
const request = http.request(options, (response) => {
response.setEncoding('utf8');
let returnData = '';
if (response.statusCode < 200 || response.statusCode >= 300) {
return reject(new Error(`${response.statusCode}: ${response.req.getHeader('host')} ${response.req.path}`));
}
response.on('data', (chunk) => {
returnData += chunk;
});
response.on('end', () => {
resolve(JSON.parse(returnData));
});
response.on('error', (error) => {
reject(error);
});
});
request.on('error', function (error) {
reject(error);
});
request.end();
}));
}
2) In the Intent, return a promise in which you call your httpGet function :
const MyIntentHandler = {
canHandle(handlerInput) {
const request = handlerInput.requestEnvelope.request;
return request.type === 'LaunchRequest' || (request.type === 'IntentRequest' && request.intent.name === 'MyIntent');
},
handle(handlerInput) {
var options = {
host: 'http://foo.com',
port: 80,
path: '/mypath',
method: 'GET'
};
return new Promise((resolve, reject) => {
httpGet(options).then((response) => {
resolve(handlerInput.responseBuilder.speak("It is done.").getResponse());
}).catch((error) => {
resolve(handlerInput.responseBuilder.speak('Thor is not available at the moment. Please try again later or contact your administrator.')
.getResponse());
});
});
},
};
This is the way to do it properly. My example is base on alexa petmatch sample.
Also we can use request module to call API as follows
const SearchIntentHandler = {
canHandle(handlerInput) {
return (
handlerInput.requestEnvelope.request.type === "IntentRequest" &&
handlerInput.requestEnvelope.request.intent.name === "SearchIntent"
);
},
handle(handlerInput) {
const query = handlerInput.requestEnvelope.request.intent.slots.SearchQuery.value;
return new Promise((resolve, reject) => {
getSearchResults(query).then((response) => {
resolve(handlerInput.responseBuilder.speak(response).getResponse());
}).catch((error) => {
resolve(handlerInput.responseBuilder.speak('This is not available at the moment.').getResponse());
});
});
}
};
function getSearchResults(query){
return new Promise((resolve, reject)=>{
let options = {
method: 'POST',
url: 'http://url.com',
headers: {'Cache-Control': 'no-cache','Content-Type': 'application/x-www-form-urlencoded' },
form: { text: query }
};
request(options, function (error, response, body) {
if (error) throw new Error(error);
let data = body ? JSON.parse(body) : ""
return resolve(data);
});
});
}
An Async/Await Example
Convert handle to an async function.
Await your promise
Example:
const SomeIntentHandler = {
canHandle(handlerInput) {...},
async handle(handlerInput) {
return handlerInput.responseBuilder.speak(await promise).getResponse();
}
};
I simply want to verify a reCAPTCHA using NodeJS and am having trouble making the simple call!
I keep getting errors missing-input-response and missing-input-secret.
Attempt 1 using request:
var request = require('request');
...
request.post(
'https://www.google.com/recaptcha/api/siteverify',
{
secret: 'MY_SECRET',
response: recaptcha
},
function (error, response, body) {
// guard
if (error) {
callback(false);
return;
}
if (response.statusCode == 200) {
console.log("BODY", body)
if (body.success) {
callback(true);
} else {
callback(false);
}
}
}
Attempt 2 using https:
var post_req;
var requestBody = {
secret: 'MY_SECRET',
response: recaptcha
};
post_req = https.request('https://www.google.com/recaptcha/api/siteverify', function (res) {
res.setEncoding('utf8');
res.on('data', function (chunk) {
console.log('CHUNK: ', chunk);
});
});
post_req.on('error', function (e) {
console.log('ERROR: ', e);
callback(false);
});
post_req.write(requestBody);
post_req.end();
The result is:
{
"success": false,
"error-codes": [
"missing-input-response",
"missing-input-secret"
]
}
Finally found a solution. It seems the issue was with the Content-Type.
This works:
var request = require('request');
...
request.post(
'https://www.google.com/recaptcha/api/siteverify',
{
form: {
secret: 'MY_SECRET',
response: recaptcha
}
},
function (error, response, body) {
if (!error && response.statusCode == 200) {
console.log(body)
}
}
);
I'm trying to get the receipt but I can't!
I already set "request_receipt" in AUTHORIZATIONS on my app and nothing change.
What I have to do to get de receipt?
<script>
var headers = {
'Accept-Language':'en_US',
'Content-Type':'application/json'
};
function callback(error, response, body) {
if(error){
console.log(error);
}else if (response.statusCode == 200) {
var jsonBody = JSON.parse(body);
headers['Authorization'] = `Bearer ${jsonBody.access_token}`;
getUserHistory(req,res);
}
}
request.post(options, callback);
});
function getUserHistory(req,res){
var options = {
url: 'https://api.uber.com/v1.2/history',
headers:headers
};
request.get(options, (error, response, body) => {
if(error){
console.log(error);
}else if (response.statusCode == 200) {
var bodyJson = JSON.parse(body);
bodyJson.history.map(function(model){
var options = {
url: 'https://api.uber.com/v1.2/requests/'+model.request_id+'/receipt',
headers:headers
};
request.get(options, (error, response, body) => {
if(error){
console.log(error);
}else if (response.statusCode == 200) {
res.send(body);
}
});
})
}
});
}
</script>
Running this code, I can see this message:
I tried to insert new image to google-picasa album using Gdata api authenticate via oauth2.0 from request.js node.js module.
My Function:
insertPhoto(options,callback){
fs.readFile('C:/Users/Public/Pictures/Sample Pictures/Chrysanthemum.jpg',"base64",function(error,data){
var userId=options.userId || 'default';
var rootUrl='https://picasaweb.google.com/data/feed/api/user/'+userId+'/albumid/'+options.albumId+'';
var body_data=gen_multipart('testing.jpg','sss',data,'image/jpeg');
request({
method:'POST',
headers:{ 'GData-Version': '2','Authorization':'Bearer' + ' ' + 'my_access_token',"Content-Type":'multipart/related; boundary="END_OF_PART"','Content-Length':body_data.length,"MIME-version":"1.0"},
body:body_data,
uri:rootUrl
},callback);
});
}
Passing options and callback to my function
insertPhoto({albumId:'5917473565459053457'},function(error,success){
if(error){
console.log(error);
}else{
console.log(success);
}
});
The following is my output
{ status: 400, message: 'Not an image.' }
Not an image.
what error is this my header and request body which i made is same as in google documentation.
refer: https://developers.google.com/picasa-web/docs/2.0/developers_guide_protocol#PostPhotos
what i did wrong can any one help me!!
I think the problem is that you use "base64" should be binary
This code seem to do the work for me:
var fs = require('fs');
var request = require('request');
exports.upload = function(fileName, options, callback) {
fs.readFile(fileName,function(error,data) {
if (error) {
callback(error, null, null);
}
else {
console.log('Read file', data.length);
var token = options.token;
var userId = options.userId || 'default';
var rootUrl = 'https://picasaweb.google.com/data/feed/api/user/'+
userId+'/albumid/'+
options.albumId+'';
request({
method:'POST',
headers:{
'GData-Version': '2',
'Authorization':'Bearer' + ' ' + token,
"Content-Type":'image/jpeg',
'Content-Length':data.length,
"MIME-version":"1.0"},
body:data,
uri:rootUrl
},callback);
}
});
};
And the calling test program:
var imageUpload = require('./imageUpload');
var parseString = require('xml2js').parseString;
imageUpload.upload('...fileName...', {
albumId: '....',
userId: '...',
token: '...'
},
function(error, response, body) {
if (body && (response.statusCode === 200 || response.statusCode === 201 || response.statusCode === 202)) {
parseString(body, function (err, result) {
console.dir(result);
if (!err) {
console.dir(result.entry['media:group'][0]['media:content'][0].$.url);
}
else {
console.error('Error', err);
}
});
}
else {
console.error('Error', response.statusCode, body);
}
});