I'm using a pattern from another project for sending JSON-data to node. In the other project it works, in this project not.
The req-object is valide, but the body is empty. Why?
Client-side:
json = { "auth_user_pkref": 2 }
json.test_id = "ANCA"
json.questions_count = 3
json.right_answers = 2
json.wrong_answers = 1
json.seconds_spent = 180
console.log('/api/answer/add', json);
$.ajax({
url: "/api/answer/add",
type: "post",
data: JSON.stringify(json),
contentType: "application/json",
success: function (data) {
},
error: function (jqXHR, textStatus, errorThrown) {
console.log("ERROR, DB error");
}
});
Server-side:
router.post('/api/answer/add', function (req, res) {
console.log('/api/answer/add: ', req.body)
Server-log:
/api/answer/add: undefined
json = { "auth_user_pkref": 2 }
json.test_id = "ANCA"
json.questions_count = 3
json.right_answers = 2
json.wrong_answers = 1
json.seconds_spent = 180
console.log('/api/answer/add', json);
$.ajax({
url: "/api/answer/add",
type: "post",
data: json,
contentType: "application/json",
success: function (data) {
},
error: function (jqXHR, textStatus, errorThrown) {
console.log("ERROR, DB error");
}
});
Try this
Related
Im using nodejs to make a call to a 3rd party API. My code code returns the correct data for an id that I'm passing in my backend. When I run my app, to retrieve the data I go to localhost:5000/api/Dls.
My code
app.get("/api/Dls", (req, res) => {
const response = {
success: false
};
if (req.user && Authorized.myToken) {
response.success = true;
response.data = {};
response.data.user = req.user;
const id = response.data.user.sub;
var options = {
method: 'GET',
url: 'https://someApi/byId/' + 'id',
headers:
{
Accept: 'application/json',
Authorization: 'Bearer' + ' ' + Authorized.myToken
}
};
request(options, function (error, response, body){
if (error) {
console.log(error);
return;
}
const data = response.body;
const userDls = JSON.parse(data)
return res.json(userDls);
});
}
});
Now I'm trying to do something like this localhost:5000/api/Dls/1234 instead of using a hard coded id in the backend
I attempted doing the following but when I enter a valid id in the url (ex. localhost:5000/api/Dls/1234) I get this "", any idea to what I should be doing?
app.get("/api/Dls/:id", (req, res) => {
const response = {
success: false
};
if (Authorized.myToken) {
response.success = true;
var options = {
method: 'GET',
url: 'https://someApi/byId/',
headers:
{
Accept: 'application/json',
Authorization: 'Bearer' + ' ' + Authorized.myToken
}
};
request(options, function (error, response, body){
if (error) {
console.log(error);
return;
}
const data = response.body;
const userDls = JSON.parse(data)
return res.json(userDls);
});
}
});
Any feedback would be appreciated!
You are not passing the route id to the api.
response.success = true;
var options = {
method: 'GET',
url: 'https://someApi/byId/' + req.params.id,
headers:{
Accept: 'application/json',
Authorization: 'Bearer' + ' ' + Authorized.myToken
}
};
i try to execute a http.request POST and my data are passed to FormValue and not in Body.
It's my first experiment in Node.js http calls so I apologize if the question is trivial.
I passed the call to a servere and i got the data at the end of the code.
function doHttpApiCall(session,callback) {
var http = require('http');
var isEndedOk;
var outValue = '';
var postData = JSON.stringify({
grant_type: 'client_credentials',
scope: 'OOB',
my_id: 'my_id_value'
});
var postOptions = {
host: 'dummyapisite.com',
path: '/t/litf9-1571295453/post',
method: 'POST',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Content-Length': postData.length
}
};
// Set up the request
var post_req = http.request(postOptions, function(res) {
var statusCode = res.statusCode;
let error;
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
}
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
const parsedData = rawData;
if (error) {
isEndedOk = false;
console.error(error.message);
console.error('Response Content=' + String(parsedData));
res.resume();
} else {
isEndedOk = true;
console.log('Response Content=' + String(parsedData));
}
callback(session.attributes,
callBack_doHttpApiCall(outValue, statusCode, session, callback, isEndedOk));
} catch (e) {
console.error(e.message);
}
});
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
post_req.write(postData);
post_req.end();
}
this is the result got by the server and the data are not in the right place.
{
"Timestamp":"2019-10-17T13:53:52.941575Z",
"Method":"POST",
"RemoteAddr":"34.245.148.80",
"ID":390940052,
"Headers":{
"Content-Length":[
"118"
],
"Content-Type":[
"application/x-www-form-urlencoded"
],
"Host":[
"ptsv2.com"
],
"X-Cloud-Trace-Context":[
"deff20a349bfb409fab118aa361ebc54/925376340939905763"
],
"X-Google-Apps-Metadata":[
"domain=gmail.com,host=dummyapisite.com"
]
},
"FormValues":{
"{\"body\":[{\"grant_type\":\"client_credentials\",\"scope\":\"OOB\",\"my_id\":\"my_id_value\"}]}":[
""
]
},
"Body":"",
"Files":null,
"MultipartValues":null
}
The problem is that you're sending a JSON body, but the Content-Type you're sending is: application/x-www-form-urlencoded, so change it to application/json
The server you're posting to, is putting the value in FormValues because you're telling them that you're sending a form (x-www-form-urlencoded)
var postOptions = {
host: 'dummyapisite.com',
path: '/t/litf9-1571295453/post',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': postData.length
}
};
I am developing a chatbot on the Facebook Messenger Platform using Node.js. This is my functioning code for setting up a text response:
const fbReq = request.defaults({
uri: 'https://graph.facebook.com/me/messages',
method: 'POST',
json: true,
qs: {
access_token: Config.FB_PAGE_TOKEN
},
headers: {
'Content-Type': 'application/json'
},
});
const fbMessage = (recipientId, msg, cb) => {
const opts = {
form: {
recipient: {
id: recipientId,
},
message: {
text: msg,
},
},
};
fbReq(opts, (err, resp, data) => {
if (cb) {
cb(err || data.error && data.error.message, data);
}
});
};
I am also able to set up an image response this way. However, when I try to make the response a button template (https://developers.facebook.com/docs/messenger-platform/send-api-reference/button-template), no response is received. No error is thrown either.
const fbInfo = (recipientId, cb) => {
const opts = {
form: {
recipient: {
id: recipientId,
},
message: {
attachment:{
type:"template",
text:"Check out our website",
payload:{
template_type:"button",
buttons:[
{
type:"web_url",
url:"https://some.website.com",
title:"Website"
}
]
}
}
}
}
};
fbReq(opts, (err, resp, data) => {
if (cb) {
cb(err || data.error && data.error.message, data);
}
});
};
Instead of form you should use json.
take a look at the code which I have written on glitch
should be something like:
request({
uri: 'https://graph.facebook.com/v2.6/me/messages',
qs: { access_token: <TOKEN> },
method: 'POST',
json: messageData}, ...)
I'm currently building a node implementation of the new Box View API and I'm getting a 202 everytime I upload a document and retrieve a session. However, if I do a curl call, I dont get a 202. Is there anyone else experiencing this issue?
Here is my Ember Implementation:
export default Ember.View.extend({
document: null,
documentID: null,
session: null,
sessionID: null,
getDocument: function() {
var self = this;
return Ember.$.ajax({
url: 'http://localhost:3000/doc',
type: 'POST',
contentType: 'application/json',
dataType: 'json',
data: JSON.stringify({ "docURL": this.textField.value })
}).then(function(response){
self.set('document', response);
self.set('documentID', response.document_id);
});
},
getSession: function() {
var self = this;
return Ember.$.ajax({
url: 'http://localhost:3000/sess/',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ "docID": this.get('documentID') })
}).
then(function(response) {
self.set('session', response);
self.set('sessionID', response.session_id);
});
}.observes('documentID'),
actions: {
upload: function() {
this.getDocument();
}
}
});
Here is my node implementation:
var https = require('https');
var requestCount = 0;
exports.doc = function(req, res) {
var docURL = req.body.docURL;
var httpReq;
var opts = {
hostname: 'view-api.box.com',
path: '/1/documents',
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Token <my token>' }
};
res.header('Access-Control-Allow-Origin', '*');
httpReq = https.request(opts, function(preq, pres) {
var output = '';
preq.on('data', function(chunk) {
output += chunk;
});
preq.on('end', function() {
output = JSON.parse(output);
output.document_id = output.id;
delete output.id;
res.json(output);
});
});
httpReq.write(JSON.stringify({ "url": docURL }));
httpReq.end();
};
exports.sess = getSession;
function getSession(req, res) {
var docID = req.body.docID;
var httpReq;
var opts = {
hostname: 'view-api.box.com',
path: '/1/sessions',
method: 'POST',
headers: { 'Content-Type': 'application/json', 'Authorization': 'Token <my token>' }
};
res.header('Access-Control-Allow-Origin', '*');
httpReq = https.request(opts, function(preq, pres) {
var output = '';
if(preq.statusCode === 202) {
setTimeout(function() {
console.log('Retrying Request :: Count(' + requestCount + ')');
if (requestCount >= 3) {
res.json({ 'error': "Retry Again.", 'time': preq.headers['retry-after'] });
return;
}
getSession(req, res);
requestCount += 1;
}, 2000);
return;
}
preq.on('data', function(chunk) {
output += chunk;
});
preq.on('end', function() {
console.log('Successful Request!');
requestCount = 0;
output = JSON.parse(output);
output.session_id = output.id;
delete output.id;
res.json(output);
});
});
httpReq.write(JSON.stringify({ "document_id": docID, "duration": 60 }));
httpReq.end();
}
But now I'm getting this error. Is there a UI that can help me remove the uploaded documents?
{
"message": "You have exceeded your document upload rate-limit.",
"type": "error",
"request_id": "49f8b480b304496987b8cf21f5850c90"
}
You have the correct approach with retry-after for sessions.
The rate limiting you're seeing is actually due to the 2-document rate limit in place for the View API beta. See the FAQ for more info.
You can use webhooks to be notified when your documents finish converting (allowing you to upload another), so you don't have to poll the /documents endpoint for status.
I have the following to update a record:
var currentTimeBeingTracked = getCurrentTimeTracked();
if (currentTimeBeingTracked != null) {
currentTimeBeingTracked.dagency_EndDateTime = new Date();
var jsonTrackedTime = window.JSON.stringify(currentTimeBeingTracked);
$.ajax({ type: "POST",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: ODataPath + "/dagency_trackedtimeSet",
data: jsonTrackedTime,
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("Accept", "application/json");
},
success: function (data, textStatus, XmlHttpRequest) {
var newTimeTracked = data.d;
RetrieveTrackedTimes();
alert("Stopped tracking your time successfully.");
window.top.document.getElementById("contentIFrame").contentWindow.location.reload();
},
error: function (XmlHttpRequest, textStatus, errorThrown) {
debugger;
alert("Couldn't stop tracking your time. " + XmlHttpRequest.responseText);
}
});
}
But I keep getting this message:
Error processing request stream. Error encountered in converting the
value from request payload for property 'CreatedOn' to type
'DateTime', which is the property's expected type. See inner exception
for more detail.
To create the record, I use the following code that works perfectly:
var trackedTime = new Object();
var timeEntryName = prompt("Please enter a name for the tracked time:", "New time entry");
if (!timeEntryName) {
return false;
}
var isBillable = confirm("Is this task billable? If Yes, press OK.");
trackedTime.dagency_name = timeEntryName;
trackedTime.dagency_StartDateTime = new Date();
trackedTime.dagency_Billable = isBillable;
var slot = new Object();
slot.Id = crmForm.ObjectId;
trackedTime.dagency_Slot = slot;
var jsonTrackedTime = window.JSON.stringify(trackedTime);
$.ajax({ type: "POST",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: ODataPath + "/dagency_trackedtimeSet",
data: jsonTrackedTime,
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("Accept", "application/json");
},
success: function (data, textStatus, XmlHttpRequest) {
var newTimeTracked = data.d;
RetrieveTrackedTimes();
alert("Started tracking your time successfully.");
window.top.document.getElementById("contentIFrame").contentWindow.location.reload();
},
error: function (XmlHttpRequest, textStatus, errorThrown) {
alert("Couldn't start tracking your time. " + XmlHttpRequest.responseText);
}
});
What is the problem? Where can I find the inner exception the message refers to?
Changed to this and it worked correctly:
if (currentTimeBeingTracked != null) {
var trackedTimeUpdated = new Object();
trackedTimeUpdated.dagency_EndDateTime = new Date();
var jsonTrackedTime = window.JSON.stringify(trackedTimeUpdated);
$.ajax({ type: "POST",
contentType: "application/json; charset=utf-8",
datatype: "json",
url: ODataPath + "/dagency_trackedtimeSet(guid'" + currentTimeBeingTracked.dagency_trackedtimeId + "')",
data: jsonTrackedTime,
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("Accept", "application/json");
XMLHttpRequest.setRequestHeader("X-HTTP-Method", "MERGE");
},
success: function (data, textStatus, XmlHttpRequest) {
var newTimeTracked = data.d;
RetrieveTrackedTimes();
alert("Stopped tracking your time successfully.");
window.top.document.getElementById("contentIFrame").contentWindow.location.reload();
},
error: function (XmlHttpRequest, textStatus, errorThrown) {
debugger;
alert("Couldn't stop tracking your time. " + XmlHttpRequest.responseText);
}
});
}
What was wrong was that I need to set the X-HTTP-Method to MERGE and specify the guid in the URL.