I'm using Express and Node. I've got some code that is posting JSON to another service that is adding it in a database.
The logic is doing what it is supposed to do, but the ajax call I am making is never returning, in the 'Network' tab in Chrome Dev tools it always shows as 'Pending' and eventually errors out with net::ERR_EMPTY_RESPONSE.
Can anyone tell me where I am going wrong?
Ajax Call
$.ajax
({
type: "POST",
url: "/order",
contentType: 'application/json',
data: orderDataJson,
success: function () {
alert("success!");
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("Something went wrong checking out!\n" + textStatus + "\n" + errorThrown);
}
});
This above routes to /order, which in turn posts the data to the other service:
app.post("/order", function(req, res, next)
{
var options = {
uri: endpoints.ordersUrl + "order",
method: 'POST',
json: true,
body: req.body
};
request(options, function(error, response, body) {
if (error !== null )
{
return;
}
if (response.statusCode == 200 && body != null && body != "")
{
if (body.error)
{
res.status(500);
res.end();
return;
}
res.end(); // UPDATED AFTER COMMENT
return;
}
console.log(response.statusCode);
});
});
This is the relevant code in the other service (it's correctly adding the content in the database)
if (request.method == 'POST')
{
switch (path)
{
// Add a new order
case "/order":
var body = '';
request.on('data', function (data) {
body += data;
});
request.on('end', function () {
var orderData = JSON.parse(body);
// Insert into orders table
var saleDate = getDate();
var ordersQuery = "INSERT into orders (customerId, saledate)" +
" VALUES (" + orderData.customerId +",'" + saleDate + "')";
db.query(ordersQuery, function(err, result)
{
if (err)
{
throw err;
}
var orderId = result.insertId;
// Insert order details
for (var i=0; i < orderData.order.length; i++)
{
var productId = orderData.order[i].productId;
var quantity = orderData.order[i].quantity;
var orderDetailsQuery = "INSERT into orderdetails (orderID, productID, quantity)" +
"VALUES (" + orderId + "," + productId + "," + quantity +")";
db.query(orderDetailsQuery, function(err, result)
{
if (err)
{
throw err;
}
});
}
});
response.writeHead(200, {
'Access-Control-Allow-Origin': '*'
});
});
break;
Try to add this in your error block:
if (error !== null ) {
res.status(500).send('Internal server error!');
return;
}
I got this fixed. The issue seem to be that express 'middleware' function should have been:
app.post("/order", function(req, res, body)
as opposed to:
app.post("/order", function(req, res, next)
From the expressjs docs:
If the current middleware function does not end the request-response cycle, it must call next() to pass control to the next middleware function. Otherwise, the request will be left hanging.
Related
I have a script where I am uploading a file to cloudinary, and then when it uploads, call my nodejs function (through js on front-end) and then update the file in my db. its working, but when I call the function, it does not render the page again. Instead nothing happens, but my db updates:
front-end script:
<script src="https://widget.cloudinary.com/v2.0/global/all.js" type="text/javascript"></script>
<script type="text/javascript">
var myWidget = cloudinary.createUploadWidget({
cloudName: 'ps',
uploadPreset: 'ld3l7evv'}, (error, result) => {
if (!error && result && result.event === "success") {
console.log('Done! Here is the image info: ', result.info);
console.log(result.info.secure_url)
var result_url = result.info.secure_url;
console.log("result url is " + result_url)
document.getElementById("url").value = result_url;
var employee_num = document.getElementById('employee_num').value
fetch('/changeProfileImage', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
result_url,
employee_num
})
})
}
}
)
backend (node.js):
app.post('/changeProfileImage', (req, res) => {
var employee_num = req.body.employee_num;
var url = req.body.result_url;
console.log("e " + employee_num)
console.log("u " + url)
var changeProfileImage = "update EMPLOYEES set (PROFILE_IMAGE)= '" + url + "' where EMPLOYEE_NUM = '" + employee_num + "'";
ibmdb.open(ibmdbconnMaster, function (err, conn) {
if (err) return console.log(err);
conn.query(changeProfileImage, function (err, rows) {
if (err) {
console.log(err);
}
console.log("succes")
conn.close(function () {
// console.log("closed the function /index");
});
})
})
})
but it is not actually refreshing / reloading the page after it updates the db. any idea?
I have jQuery as client script and node JavaScript server as back-end.
I used to post the request to node server for getting data. Please find my AJAX call below.
My problem is even if my response is set to success it always comes in error function of the jquery.AJAX method.
And error object looks like
$.ajax({
url : 'http://127.0.0.1:3000/uploadcontent/fileUpload',
type : 'post',
data : formData,
enctype : 'multipart/form-data',
processData : false,
contentType : false,
error : function(error,jqXHR, exception) {
errorMessage(error);
console.log(JSON.stringify(error))
console.log(exception +" : "+error);
},
success : function(data) {
alert(data);
if (data.sucess){
successMessage(data.returnMessage);
} else {
alert('error');
if (data.returnObj != null) {
} else{
errorMessage(data.returnMessage);
}
}
}
})
Now, find below my node JavaScript route for the above request.
app.post('/fileupload', function(req, res) {
var fstream;
var fileName, bunchId, standard, userKey, subject, unit, chapter, topic;
req.pipe(req.busboy,function(err) {
if(err) {
console.log("ERROR: " + err.code + " (" + err.message + ")");
return;
}
});
req.busboy.on('file', function (fieldname, file, filename) {
console.log("Uploading: " + filename);
fstream = fs.createWriteStream(config.content_upload_path.pdf_path + filename + 'abc');
file.pipe(fstream,function(err) {
if(err) {
console.log('pipe error due to stream')
console.log("ERROR: " + err.code + " (" + err.message + ")");
return;
}
});
fstream.on('close', function () {
fileName = filename;
fileObject = file;
uploadFile(paramData, res)
res.redirect('back');
console.log('method complete')
});
fstream.on('error', function (err) {
console.log('stream on error event')
console.log(err)
generateWebServiceResponse(res, false, null, 200, err)
console.log(res);
res.send()
});
});}
generateWebServiceResponse method looks like this:
function generateWebServiceResponse(response, isSuccess, result, httpStatus,
returnMessage) {
response.json({
isSucess : isSuccess,
returnObj : result,
returnMessage : returnMessage,
resultCode : 0,
httpStatus : httpStatus
});}
Even in case of failure it should land in success function with isSuccess = false. But in each case it is landed in error case.
I am also not able to solve access origin error mentioned in the attached image.
It happened because of CORS. You must enable CORS for your route. The simplest way is using Node.js CORS middleware
I am new to node and async...
I am getting an error saying I can't set headers after they sent when I am sending a response back to api-ai
Any idea why?
Below is the code for function - getUserFirstName(userId, name, callback):
var name = "";
function getUserFirstName(userId, name, callback) {
console.log('withParams function called');
request({
method: 'GET',
uri: "https://graph.facebook.com/v2.6/" + userId + "?fields=first_name,last_name,profile_pic,locale,timezone,gender&access_token=" + FB_PAGE_ACCESS_TOKEN
},
function (error, response) {
if (error) {
console.error('Error while userInfoRequest: ', error);
} else {
if(!typeof response.body != 'object'){
var body = JSON.parse(response.body);
name = body.first_name;
callback(null,name);
}else{
name = response.body.first_name;
callback(null,name);
}
}
});
}
Here is the code being executed:
app.post('/webhook/', (req, res) => {
var data = JSONbig.parse(req.body);
var action = data.result.action;
var facebook_message = [];
if(action == "input.welcome"){
var userId = data.originalRequest.data.sender.id;
async.series([
function(callback) {
getUserFirstName(userId, name, callback);
}
], function(err,results) {
if (results != undefined){ // results = "John"
facebook_message = [{
"text":"Heyyyoo. Welcome!"
}]
}else{
facebook_message = [{
"text":"Hey " + results +"! Welcome!" // Hey John! Welcome!
}]
}
res.json({ // line 308 - error here!
speech: "Greetings",
displayText: "Greetings",
"data": {
"facebook": facebook_message
},
source: "webhook"
});
});
}
// BUNCH OF LONG AND MESSY CODES OVER HERE...
return res.status(200).json({
status: "ok"
});
Error
Error: Cant set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:356:11)
at ServerResponse.header (/app/node_modules/express/lib/response.js:719:10)
at ServerResponse.send (/app/mode_modules/express/lib/response.js:164:12)
at ServerRespose.json (/app/mode_modules/express/lib/response.js:250:15)
at /app/src/app.js: 308:15
at /app/node_modules/async/dist/async.js:3694:9
at /app/node_modules/async/dist/async.js:356:16
at replenish (/app/node_modules/async/dist/async.js:877.25)
at iterateeCallback (/app/node_modules/async/dist/async.js:867:17)
at /app/node_modules/async/dist/async.js:840:16
Remove the following:
return res.status(200).json({
status: "ok"
});
var Attendance = require('../../../collections/attendance').Attendance;
var moment = require('moment');
module.exports = function(app) {
app.get('/api/trackmyclass/attendance', function(req, res) {
var data = req.body;
data['user'] = req.user;
Attendance.getByUser(data, function(err, d) {
if (err) {
console.log('This is the err' + err.message);
res.json(err, 400);
} else {
var job = d['attendance'];
if (typeof job != undefined) {
res.json(job);
console.log('This is it' + job['status']);
} else
res.json('No data Present', 200);
}
});
});
app.post('/api/trackmyclass/attendance', function(req, res) {
var data = req.body;
data['user'] = req.user;
Attendance.create(data, function(err, d) {
if (err) {
console.log('This is the err' + err.message);
res.json(err, 400);
} else {
var attendance = d['attendance'];
if (typeof job != undefined) {
console.log('Attendance record created' + attendance);
res.json(attendance);
} else
res.json('No data Present', 200);
}
});
});
}
This is the api code I to which I need to make the GET and POST request. But I have no idea how to do it.
It looks like your code is using express which would normally be good for building and API for your app. However to make a simple request to a third party api and staying in node.js why not try the request module which is great. https://www.npmjs.org/package/request
Your example does not show what the path of the request is or if you need any additinal headers etc but here is a simple example of a GET request using request.
var request = require('request');
function makeCall (callback) {
// here we make a call using request module
request.get(
{ uri: 'THEPATHAND ENDPOINT YOU REQUEST,
json: true,
headers: {
'Content-Type' : 'application/x-www-form-urlencoded',
}
},
function (error, res, object) {
if (error) { return callback(error); }
if (res.statusCode != 200 ) {
return callback('statusCode');
}
callback(null, object);
}
);
}
or jquery .ajax from a front end client direcct to your path
$.ajax({
url: "pathtoyourdata",
type: "GET",
})
.done(function (data) {
//stuff with your data
});
Folks,
I keep beating my head against this problem. In essence, I have a form which submits a string value to search through DynamoDB RangeKey.
If the form contains "NEW Y" the function seems to break. If I stick "NEW%20Y", things work as expected. I see the following error if the space is used:
error: socket hang up
Somewhere in this code it must not be passing spaces correctly. What is baffling that 'some' spaces work, some dont.
exports.nameSearch = function (req, res) {
getJSON = function(options, onResult){
//console.log("rest::getJSON");
var prot = options.port == 8443 ? https : http;
var req = prot.request(options, function(res)
{
var output = '';
console.log(options.host + ':' + res.statusCode);
res.setEncoding('utf8');
res.on('data', function (chunk) {
output += chunk;
});
res.on('end', function() {
var obj = JSON.parse(output);
onResult(res.statusCode, obj);
});
});
req.on('error', function(err) {
res.send('error: ' + err.message);
});
req.end();
};
if (!req.session.username) {
res.redirect('/login');
} else {
options = {
host: 'api.me.com',
port: 8443,
path: '/usr/name/'+req.body.name,
method: 'GET',
rejectUnauthorized: false,
requestCert: true,
agent: false,
headers: {
'Content-Type': 'application/json'
}
};//options
getJSON(options,function(statusCode, result) {
console.log("onResult: (" + statusCode + ")" + JSON.stringify(result));
// Check if we found anything
status = JSON.stringify(result.Count)
if (status == 'undefined') {
console.log ('Nothing Found by the name,', req.body.name)
var count = '0'
res.render('user/nameSearch', { title: 'title', count: count, req: req });
} else {
results = JSON.stringify(result)
console.log ("results 1 ok , ", results)
results = JSON.parse(results)
console.log ("results 2 ok , ", results)
res.render('base/nameSearch', { title: 'title', baseResults: results, req: req })
}
});// JSON
} // else
};
If the form contains "NEW Y" the function seems to break. If I stick "NEW%20Y", things work as expected.
That means somewhere you are url decoding your input, so you need to figure out which middleware does this. Possibly the built-in unescape function. But as it stands your question is too general for me to narrow down where urlencoded input is expected.