How can I fix set headers in node js? - javascript

I am trying to redirect from the condition of a mysql to a get method but it does not work. How could I solve it?
app.post('/responses/',(req,res)=>{
var {text, context ={} } = req.body;
var params = {
input: {text},
workspace_id: '07',
context
}`
`assistant.message(params,(err,response) => {
if(err){
res.status(500).json(err);
}
else {
res.json(response);
console.log(JSON.stringify(response, null, 2));
}
if(response.context.rfc){
var RFC = response.context.rfc;
connection.connect(function(err) {
if (err) throw err;
connection.query(`SELECT * FROM test where RFC = '${RFC}'`, function (err, result, fields) {
if(result.length){
console.log("login");
}
else {
console.log('no login');
res.redirect('/home'); //Her not redirect.
}
});
});
}
});
});
Because show this error: hrow err; // Rethrow non-MySQL errors ^Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client

The error message indicates you are trying to set headers after the response is already sent. From your sample code, looks like your API call (whatever assistant.message is) is returning RFC. You then attempt to redirect to another page, but you've already called res.json, which begins sending a response to the browser.
You need to refactor your controller a bit so that you only call res.redirect or res.json, not both.

Related

How to implement ExpressJS Error Handling so that it shows different errors for different HTTP Status codes

I wanna implement this task and I'm unable to understand how to do it.
Create an error on /error path and pass it to the next function. Depending on the type of error message you are showing, use proper error status codes to show the error.
I tried to use this logic but it doesn't work.
app.use((req, res, next) => {
if (req.status(403)) {
res.send("<h1>ERROR FOUND</h1>");
next();
} else if (req.status(404)) {
res.send("<h1>PAGE NOT FOUND</h1>");
next();
} else if (req.status(500)) {
res.send("<h1>INTERNAL SERVER ERROR</h1>");
next();
} else if (req.status(200)) {
res.send("<h1>COnnected!</h1>");
next();
} else console.log("No error");
});
The whole code is available at:
https://github.com/iamdakshak/react-training-work/blob/master/Node%20Assignments/Assignment%203%20-%20Sever%20basics%2C%20Middlewares%2C%20HTTP%20methods/index.js
How can it be implemented?
There is no status() method on the request object in Express.
The status code is stored in the response object, to check it:
if (res.statusCode === 500)
next()
To set the status code use:
res.status(500)
You could use an object with messages
const messages = {
403: "<h1>ERROR FOUND</h1>",
404: "<h1>PAGE NOT FOUND</h1>",
500: "<h1>INTERNAL SERVER ERROR</h1>",
200: "<h1>COnnected!</h1>",
}
const req = {statusCode: "200"}
if(messages[req.statusCode]){
console.log(messages[req.statusCode]);
// res.send(messages[req.statusCode])
} else {
console.log("No error");
}

nodejs callback: doesn't detect any errors, just like if there were no error at all

Node js/Javascript doesn't catch the error while querying mysql server
The nodejs server queries the submittedName from form, checks the database along with submittedName. If submittedName matches with the submittedName, renders success. If it doesn't match, it should render notfound.
But indeed, it does not. Instead, it renders success. Even on wrong input.
app.post("/whatisyourname", (req, res) => {
var submittedName = req.body.details;
console.log(details);
//query the mysql database
conn.query(
"SELECT * FROM giftapp where name= ?",
submittedName,
(err, rs) => {
//handle the error
if (err) {
console.log(err);
//while it should render the "notfound" file,
//it renders "success"
res.render("notfound");
} else {
//if no error, render success
res.render("success", { myR: rs[0] });
}
}
);
I expect to be forwarded to "notfound" in case of wrong input or just any error
And to be forwarded to "success" in case of correct input
The express server or sql connection or callback won't throw any error in this case. You will get an error if something goes wrong while querying the db, i.e Invalid query or connection error etc. In your case the query executes successfully and gives you the result which is an empty array. You need to manually check and return the result. Change your code like:
app.post("/whatisyourname", (req, res) => {
const submittedName = req.body.details;
console.log(details);
//query the mysql database
conn.query(
"SELECT * FROM giftapp where name= ?",
submittedName,
(err, results) => {
if (err) {
console.log(err);
res.render("notfound");
} else {
if (results && results.length > 0) {
res.render("success", { myR: results[0] });
} else {
res.render("notfound");
}
}
});
});
Hope this helps :)
var submittedName = req.body.details;
var sql = 'SELECT * FROM giftapp WHERE name = ?';
con.query(sql, [submittedName], function (err, result) {
if (err) res.render("notfound"); // if you view is called notfound.ejs remove the space between not and found.
console.log(result);
res.render("success", { myR: result[0] }); // need success.ejs
});

res.json not returning response

My res.json in my first block of code works, but in the else part of my if statement, it does not. The block that doesnt work, checks for a record in a database then im trying to return the response but im not receiving it.
I've checked and the response is a string, I thought it would have worked as the top part of the code successfully returns the string and it shows in dialogflow (where im trying to return it)
The response is successfully consoled right before the res.json but I do not receive it from the source of the request.
code:
app.post('/webhook/orderinfo', (req, res) => {
const intent = req.body.queryResult.intent.displayName;
const domain = "chatbotdemo.myshopify.com";
const order = req.body.queryResult.parameters["number-sequence"];
if (intent.includes('Order Number')) {
url = "https://test-hchat.com/api/orders/" + domain + "/" + order;
request(url)
.then(function (response) {
order_res = JSON.parse(response)
order_res["fullfillmentText"] = "Hi, Please find your order details below:";
res.json({
"fulfillmentText": JSON.stringify(order_res)
})
})
.catch(function (err) {
console.log(err)
});
// THIS PART DOESNT RETURN THE RESPONSE.
} else {
const domain = 'testStore'
db.getClientsDialog(domain, intent, (response) => {
const fullResponse = response.response
res.json({
fullResponse
})
})
}
});
The database code:
getClientsDialog: function (domain, intent, callback) {
MongoClient.connect('mongodb://efwefewf#wefwef.mlab.com:15799/wefwef', function (err, client) {
if (err) throw err;
var db = client.db('asdsad');
db.collection('dialog').findOne({ domain: domain, intent: intent }, function (err, doc) {
if (!err) {
callback(doc)
} else {
throw err;
callback(err)
}
client.close();
});
console.dir("Called findOne");
});
}
Could it be because this second use of the res.json in the else statement, is trying to call the db first and therefore the link is lost to send the data back?

Node.js + OracleDB : ORA-01036: illegal variable name/number

Hello you beautiful people you.
I'm trying to create REST APIs using node.js connected to an OracleDB, but i'm pulling my hair out trying to get these stupid bind variables working.
Here's my code:
app.get('/mailsummary/:SCHEMA', function (req, res) {
"use strict";
oracledb.getConnection(connAttrs, function (err, connection) {
if (err) {
// Error connecting to DB
res.set('Content-Type', 'application/json');
res.status(500).send(JSON.stringify({
status: 500,
message: "Error connecting to DB",
detailed_message: err.message
}));
return;
}
connection.execute("select * from :SCHEMA.event#db3", [req.params.SCHEMA], {
outFormat: oracledb.OBJECT // Return the result as Object
}, function (err, result) {
if (err || result.rows.length < 1) {
res.set('Content-Type', 'application/json');
var status = err ? 500 : 404;
res.status(status).send(JSON.stringify({
status: status,
message: err ? "Error getting vendor mailing summary." : "Vendor or DB does nto exist.",
detailed_message: err ? err.message : ""
}));
} else {
res.contentType('application/json').status(200).send(JSON.stringify(result.rows));
}
// Release the connection
connection.release(
function (err) {
if (err) {
console.error(err.message);
} else {
console.log("GET /mailsummary/" + req.params.SCHEMA + " : Connection released");
}
});
});
});
});
For some reason i'm getting the error
OracleDB : ORA-01036: illegal variable name/number
If I remove the bind variable, assign a static value and remove "req.params.SCHEMA" after the sql statement and leave the brackets blank, it works.
connection.execute("select * from peeps.event#db3", [], {
outFormat: oracledb.OBJECT // Return the result as Object
I know it's got to be something simple with the way i'm pulling in the bind variable, but i'm pulling my hair out.
Please help me Obi-Wan Kenobi... you're my only hope.
Thanks!
Bind variables are placeholders used to transfer data between database and client program. You are trying to transfer the text of the SQL statement - your usage won't work.
This bind behavior is not specific to node-oracledb; it's the way Oracle works. It helps keep data and statement text separate.
There is some general bind info at: http://docs.oracle.com/database/122/LNOCI/binding-and-defining-in-oci.htm#GUID-77A26CEA-1C41-46A2-866C-622F9FEB5482

Insert error in rethindb using node

I am new to rethinkdb.
When I try out the sample code in https://github.com/rethinkdb/rethinkdb-example-nodejs/tree/master/todo-angular-express
function create(req, res, next) {
var todo = req.body;
todo.createdAt = r.now(); // Set the field `createdAt` to the current time
r.table('todos').insert(todo, {returnVals: true}).run(req._rdbConn, function(error, result) {
if (error) {
handleError(res, error)
}
else if (result.inserted !== 1) {
handleError(res, new Error("Document was not inserted."))
}
else {
res.send(JSON.stringify(result.new_val));
}
next();
});
}
I got the following error:
500 Internal Server Error
{"error":"return_vals renamed to return_changes in:\nr.table(\"todos\").insert({title: r.json(\"\"abcde\"\"), completed: r.json(\"false\"), createdAt: r.now()}, {returnVals: true})\n
And then I tried out the sample code in http://rethinkdb.com/docs/examples/node-todo/
function create(req, res, next) {
var todo = req.body; // req.body was created by `bodyParser`
todo.createdAt = r.now(); // Set the field `createdAt` to the current time
r.table('todos').insert(todo, {returnChanges: true}).run(req._rdbConn, function(error, result) {
if (error) {
handleError(res, error)
}
else if (result.inserted !== 1) {
handleError(res, new Error("Document was not inserted."))
}
else {
res.send(JSON.stringify(result.changes[0].new_val));
}
next();
});
}
I got the following error:
500 Internal Server Error
{"error":"Unrecognized optional argument returnChanges. in:\nr.table(\"todos\").insert({title: r.json(\"\"abcde\"\"), completed: r.json(\"false\"), createdAt: r.now()}, {returnChanges: true})\n "}
It seems that rethinkdb have changed returnVals to return_changes / returnChanges, and the argument of insert().
And I have the problem fixed when I used return_changes.
What is the right way to work on insert in latest version?
Do rethinkdb always changes its syntax?
this is indeed a bug in the example code. I've opened https://github.com/rethinkdb/rethinkdb-example-nodejs/issues/3 so we can fix it.
Your second problem with returnChanges not being recognized might come from using an old RethinkDB node driver. Have you tried updating the driver? http://rethinkdb.com/docs/install-drivers/javascript/

Categories