As the uri is generated is as expected and list data is shown in page but while sending the req in request method, 500 error occurs instead of retruning body.
uri: http://yufluyuinnepal.com/?vTRIPTYPE=O&vOPSID=O&vSTRFROM=KTM&vSTRFROMTXT=&vSTRTO=PKR&vSTRTOTXT=&vFLIGHTDATE=27-Nov-2018&vRETURNDATE=27-Nov-2018&vADULT=1&vCHILD=0&vNATIONALITY=NP&vNATIONALITYTXT=Nepal&
const uri = `http://yufluyuinnepal.com/?${queryString(query)}`;
console.log(uri);
const req = {
uri: uri,
};
request(req, (error, response, body) => {
if (error) {
return reject(error);
}
if (response.statusCode !== 200) {
return reject(new Error(`Expected 200 but got ${response.statusCode}`));
}
return resolve(body);
});
Let me know how can i return body and what is wrong in my code.
In Request npm module, specify what kind of request is it (GET/POST etc)
// Example GET Request
var options = {
method: "GET",
url:
uri,
headers:
{
// headers as per documentation
}
};
request(options, (error, response, body) => {
if(error){}
if(response.statusCode !== 200){}
return resolve(body);
})
This is your current implementation with a callback function.
const req = {
uri: uri,
method: 'GET'/'POST'
};
request(req, (error, response, body) => {
if (error) {
console.log(error);
}
if (response.statusCode !== 200) {
//Do something
}
console.log(body);
//Do something
});
When using request-promise module you should write something like this
var rp = require('request-promise');
const req = {
uri: uri,
method: 'GET'/'POST'
}
rp(req)
.then((res) => {
//Do something
})
.catch((error) => {
//Do something with error
});
Please try this
let requestp=require('request-promise');
var options = {
method: 'POST',
url: 'uri',
resolveWithFullResponse: true,
headers: {
'Accept': 'application/json',
'Content-Type' : 'application/json'
},
body: TextedValue
};
await requestp(options).then(async function(Content){
await requestp(options).then(async function(response){
if (await response.statusCode == 200)
{
console.log(Content); // in ur case it is body
}
else
{
console.log("Response code "+response.statusCode+" .Try Again Later")
}
})
})
Related
I have this cloud function that append a line to a Google Spreadsheet:
function addLine(req, res) {
res.set("Access-Control-Allow-Origin", "*");
if (req.method === "OPTIONS") {
res.set("Access-Control-Allow-Methods", "POST");
res.set("Access-Control-Allow-Headers", "Content-Type");
res.set("Access-Control-Max-Age", "3600");
return res.status(204).send("");
}
const isReqValid = validateReq(req);
if (!isReqValid) return res.send("Not valid request!"); // <--
const { body } = req;
const isBodyValid = validateData(body);
if (!isBodyValid) return res.send("Not valid payload!"); // <--
return appendData(body)
.then(() => res.send("Added line"))
.catch((err) => {
res.send("Generic error!");
});
}
function validateReq(req) {
if (req.method !== "POST") return false;
return true;
}
function validateData(data) {
// do something and return true or false
}
async function appendData(data) {
const client = await auth.getClient();
return sheets.spreadsheets.values.append(
{
spreadsheetId: ...,
auth: client,
range: "A1:B",
valueInputOption: "RAW",
resource: { values: [data] },
},
);
}
I use it in this way:
async collaborate(data: CollaborateDatum) {
await post('...cloudfunctions.net/addLine', data)
}
async function post(url, data) {
return fetch(url, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
}
How can I "read" the errors Not valid request! and Not valid payload!? Because if I tried to append a line with not valid data, I get status code 200 but in Chrome Dev Tools -> Network -> Response, the response is Not valid payload! but I don't know how to catch this error.
Thanks a lot!
You should be able to get any response text that's passed back like this:
let responseText = await (await post('...cloudfunctions.net/addLine', data)).text();
I have a method that uses node-fetch to make a POST call to update a profile object in a table via an API. If an invalid profileId is provided (status 404) the promise still resolves. What's the best way to handle it so that I can only accept status 200? The method is defined as:
async function updateUserProfileSocketId(profileId, socketId) {
const body = { id: profileId, socketId };
try {
const response = await fetch(`${API_URL}/updateUserProfile`, {
method: 'post',
body: JSON.stringify(body),
headers: { 'Content-Type': 'application/json' },
});
if (response.status !== 200) {
throw new Error(response.status);
}
} catch (err) {
console.log(`updateUserProfileSocketId Error: ${err}`);
}
}
And the method is called in a service class like this:
onInit(socket) {
socket.on('init', (profile) => {
Promise.resolve(updateUserProfileSocketId(profile.id, socket.id))
.then((response) => {
if (response === null || response === undefined) {
console.log(`Unable to find profile ${profile.id}`);
socket.conn.close();
} else {
users.push(profile.id);
}
})
.catch((err) => {
console.log(err);
});
});
}
This seems to work, but I'm not sure if this is the best way to handle this. Any ideas?
If the response status is not 200, you throw an exception that will immediately be caught again. This is probably not what you want. You can leave the catch block for logging purposes, but you should rethrow the exception:
async function updateUserProfileSocketId(profileId, socketId) {
const body = { id: profileId, socketId };
try {
const response = await fetch(...);
if (response.status !== 200) {
throw new Error(response.status);
}
} catch (err) {
console.log(`updateUserProfileSocketId Error: ${err}`);
throw err;
}
}
The same thing applies to the catch-handler inside the socket-callback.
However, removing the try/catch/log/rethrow logic and handling the exception centrally would be cleaner.
I am a beginner to callback concept and looking for a solution to my problem.
I calling third party API using request package in node.js here is the code:
In reusable library file: auth.js
let getAuthToken = () => {
let authToken;
var options = {
'method': 'GET',
'url': 'https://<apiURL>/V1/auth_token',
'headers': {
'Authorization': 'Basic <token>'
}
};
request(options, (error, response) => {
if (error) {
throw new Error(error);
} else {
authToken = JSON.parse(response.body);
}
});
return authToken;
}
on my route: http://127.0.0.1:3000/api/v1/musics/authorize-account, I am calling my controller function named "getAuthorizationToken()"
controllerfile: music.controller.js
const auth = require('../middleware/auth');
let getAuthorizationToken = async (req, res, next) => {
let token = await auth.getAuthToken();
console.log(auth.getAuthToken());
res.send(token);
}
Problem is the controller function is getting executed completely and then the third party API is being called event I have added await to the function.
Do explain to me the problem I am facing and any workaround solution will be heartily helpful.
You have to return a promise to be able to await something and have it work as expected:
let getAuthToken = () => {
let authToken;
var options = {
'method': 'GET',
'url': 'https://<apiURL>/V1/auth_token',
'headers': {
'Authorization': 'Basic <token>'
}
};
return new Promise((resolve, reject) => {
request(options, (error, response) => {
if (error) {
reject(error);
} else {
authToken = JSON.parse(response.body);
resolve(authToken);
}
});
})
}
await is only useful on promises. In your case your getAuthToken does not return an promise. But you can change it.
let getAuthToken = () => {
return new Promise((res, rej) => {
let authToken;
var options = {
method: "GET",
url: "https://<apiURL>/V1/auth_token",
headers: {
Authorization: "Basic <token>"
}
};
request(options, (error, response) => {
if (error) {
rej(error);
} else {
authToken = JSON.parse(response.body);
res(authToken);
}
});
});
};
In addition you should also wrap your await in a try / catch
let getAuthorizationToken = async (req, res, next) => {
try {
let token = await auth.getAuthToken();
console.log(token);
return res.send(token);
} catch(err) {
console.log(err);
return res.status(500).send(err);
}
}
Instead of an 500 error you should send an different error code like:
400 Bad request: If there are some missing credentials like the token is missing
401 Unauthorized: If the token is wrong
I would like to retry my request in a promise. I would like launch my refresh if I have always an 401 error as a loop : (if I have 401 loop on refresh until 200)
I tried with this :
const request = require('request');
let conf = require('../conf');
let core_service = require('coreService');
let self = module.exports = {
get_count_questions: function() {
return new Promise((resolve, reject) => {
request({
method: 'GET',
uri: 'http://api/count-questions',
auth: {
'bearer': conf.token
},
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
resolve(body);
} else if (!error && response.statusCode === 401) {
core_service.refreshToken().then((data) => {
console.log('token refresh');
return self.get_count_questions();
})
} else {
reject(error);
}
})
});
}
};
I tried with just 'self.get_count_questions();' without return, but it's not work. I have not error message, just my app freeze.
I see in my console.log "token refresh", but after my app freeze...
Edit
I modified with this, It's like better but the refresh token it's very slow. Just before 401, my app stop, and after about 1 minutes 40 seconds, run:
else if (!error && response.statusCode === 401) {
console.log('need refresh token');
core_service.refreshToken()
.then((response) => {
console.log(response);
resolve(self.get_count_questions())
} );
}
My refreshToken function :
refreshToken: function () {
return new Promise((resolve, reject) => {
request({
method: 'GET',
uri : 'http://api/refresh',
auth : {
'bearer': conf.token
},
json : true
}, function (error, response, body) {
console.log('=====> refresh token <======');
conf.token = body.data;
console.log('new Token');
console.log('=====> end refresh token <======');
if (!error && response.statusCode === 200) {
resolve('Refresh token successful');
} else {
reject('Error refresh');
}
})
});
}
If I refresh my token on each request, I have a problem :
if (!error && response.statusCode === 200) {
core_service.refreshToken().then((data)=> {
resolve(body);
});
}
You have to resolve the returned promise. When you resolve using a promise, you basically say, complete this promise with the result of that promise.
var prom = function() {
return new Promise((resolve, reject) => {
console.log('request start')
setTimeout(() => {
console.log('request finish')
let ran = Math.random();
if (ran < 0.1)
resolve('success');
else if (ran >= 0.1 && ran < 0.98)
setTimeout(() => {
console.log('retry');
resolve(prom());
}, 500);
else
reject('error');
}, 500);
});
};
prom().then(console.log.bind(console), console.log.bind(console));
So you should update your else if block like this:
else if (!error && response.statusCode === 401) {
console.log('need refresh token');
core_service.refreshToken()
.then(() => resolve(self.get_count_questions()));
}
You're making a recursive call, but you're never actually doing anything with its promise. Therefore, your original promise never resolves.
You need to pass the promise from the recursive call (to refreshToken().then()) to resolve().
Now you almost have it.
However:
return core_service.refreshToken()
.then(self.get_count_questions);
You're returning that to the request() callback; that return value is not used.
Instead, you need to resolve your original promise to the new promise from then(), by passing it to your original resolve() function:
resolve(core_service.refreshToken().then(...));
I know that is not optimal solution but it might helps
const request = require('request');
let conf = require('../conf');
let core_service = require('coreService');
let self = module.exports = {
get_count_questions: function() {
return new Promise((resolve, reject) => {
request({
method: 'GET',
uri: 'http://api/count-questions',
auth: {
'bearer': conf.token
},
json: true
}, function (error, response, body) {
try{
if (!error && response.statusCode === 200) {
resolve(body);
} else if (!error && response.statusCode === 401) {
throw new Error(response.statusCode);
} else {
reject(error);
}
}catch(exc){if(exc === 401){
core_service.refreshToken().then((data) => {
console.log('token refresh');
return self.get_count_questions();
})
}
}
})
});
}
};
You need to call the initial resolve/reject functions after you retried the request:
let self = module.exports = {
get_count_questions: function() {
return new Promise((resolve, reject) => {
request({
method: 'GET',
uri: 'http://api/count-questions',
auth: {
'bearer': conf.token
},
json: true
}, function (error, response, body) {
if (!error && response.statusCode === 200) {
resolve(body);
} else if (!error && response.statusCode === 401) {
core_service.refreshToken().then((data) => {
console.log('token refresh');
self.get_count_questions().then((data) => {
// call initial resolve function
resolve(data);
}).catch((error) => {
// call initial reject function
reject(error);
});
}).catch((error) => {
// reject if refreshToken fails
reject(error);
});
} else {
reject(error);
}
})
});
}
};
You also have to make sure, that the second call actually resolves/rejects and doesn't land in another 401. Because else you have an infinite recursion.
I want to request a simple JSON File in NodeJS. With Javascript and jQuery it works like a charm:
$(document).ready(function() {
$.getJSON('https://www.younow.com/php/api/broadcast/info/curId=0/user=Peter', function(json) {
if (json["errorCode"] > 0) {
console.log("Offline");
$('#ampel').addClass('red');
} else {
console.log("Online");
$('#ampel').addClass('green');
}
});
})
But i can't get it to work with NodeJS:
var request = require('request');
var options = {
url: 'https://www.younow.com/php/api/broadcast/info/curId=0/user=Peter',
headers: {
'content-type': 'application/javascript'
}
};
function callback(error, response, body) {
console.log(response.statusCode);
}
request(options, callback);
The StatusCode is always 403 and i can't work with the data. Can somebody help me, so i can get the same result like with jQuery?
Thanks!
I was able to find the solution with Mike McCaughan's help:
I had to send a different user-agent to get a 200 response. The code looks like this now:
var options = {
url: 'https://www.younow.com/php/api/broadcast/info/curId=0/user=',
headers: {
'User-Agent': 'request'
}
};
function callback(error, response, body) {
var str = JSON.parse(body);
if (str.errorCode > 0) {
...
} else {
...
}
}
request(options, callback);