MEAN CRUD error crash cant set headers - javascript

So my CRUD app at this time, does two things, keeps sending an infinite empty list. But not just that, when I try to delete something I get this error... Jump below for the api code. Also if you see anything that might contribute to an infinite list lemme know.
C:\Users\\Desktop\Todo List\node_modules\mongoose\lib\utils.js:419
throw err;
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:691:11)
at ServerResponse.res.setHeader (C:\Users\\Desktop\Todo List\node_modul
es\express\node_modules\connect\lib\patch.js:63:22)
at ServerResponse.res.set.res.header (C:\Users\\Desktop\Todo List\node_
modules\express\lib\response.js:526:10)
at ServerResponse.res.json (C:\Users\\Desktop\Todo List\node_modules\ex
press\lib\response.js:193:36)
at Promise.<anonymous> (C:\Users\\Desktop\Todo List\routes\api.js:45:21
)
at Promise.<anonymous> (C:\Users\\Desktop\Todo List\node_modules\mongoo
se\node_modules\mpromise\lib\promise.js:162:8)
at Promise.EventEmitter.emit (events.js:95:17)
at Promise.emit (C:\Users\\Desktop\Todo List\node_modules\mongoose\node
_modules\mpromise\lib\promise.js:79:38)
at Promise.fulfill (C:\Users\\Desktop\Todo List\node_modules\mongoose\n
ode_modules\mpromise\lib\promise.js:92:20)
at C:\Users\\Desktop\Todo List\node_modules\mongoose\lib\query.js:1736:
26
routes api code
var Todo = require('../app/models/todos').Todo;
exports.read = function(req, res) {
// use mongoose to get all todos in the database
Todo.find(function(err, todos) {
// if there is an error retrieving, send the error. nothing after res.send(err) will execute
if (!err)
res.send(err)
res.json(todos); // return all todos in JSON format
});
};
// create todo and send back all todos after creation
exports.create = function(req, res) {
// create a todo, information comes from AJAX request from Angular
Todo.create({text : req.body.text}, function(err, todos) {
if (err)
res.send(todos);
// get and return all the todos after you create another
Todo.find(function(err, todos) {
if (err)
res.send(err)
res.json(todos);
});
});
};
// delete a todo
exports.delete = function(req, res) {
Todo.remove({_id : req.params._id
}, function(err, todos) {
if (err)
res.send(todos);
// get and return all the todos after you create another
Todo.find(function(err, todos) {
if (err)
res.send(err)
res.json(todos);
});
});
};
//Update a todo
exports.update = function(req, res) {
Todo.findById(req.params._id, function(err, todos){
todos.text = req.body.text;
console.log(todos);
todos.save(function() {
if (!err) {
res.send(todos);
} else if (err) {
res.send(err);
}
Todo.find(function(err, todos) {
if (err)
res.send(err)
res.json(todos);
});
});
});
};

I usually see this error when I'm using res multiple times in my Express route by mistake. Be sure that in route handler (function) you are only using res once.
For example
app.get('/foo', doFoo);
function doFoo(req, res) {
res.send('foo');
res.send('bar');
}
won't work since you're trying to use res twice which internally calls res.end() if I'm not mistaken.
Edit: As it turns out, I think I see the problem in your code.
// create a todo, information comes from AJAX request from Angular
Todo.create({text : req.body.text}, function(err, todos) {
if (err)
res.send(todos);
// get and return all the todos after you create another
Todo.find(function(err, todos) {
if (err)
res.send(err)
res.json(todos);
});
});
Here, you're using res.send(todos) in the event that you receive an error from your first call to Todo.create. Assuming you do receive an error here, your code will still attempt Todo.find. Once that happens, it will then try res.json(todos) thereby firing two responses and resulting in the error that you see about not being able to set response headers after they're already sent. I think you can fix your code by using actual else statements to ensure you don't send two responses.
Todo.create({text:req.body.text}, function(err, todos){
if (err) {...}
else {
.. your else code here
}
});

Related

Node.js Express execute inside app.post()

I have a problem right now that I can't solve by myself. I assume you know more here. I'm just getting started.
By using the following code I'm getting a list of customers:
app.get("/customers", customers.findAll);
I wanted to add authentication. But now I don't know how to execute "customers.findAll" and get the value as JSON.
app.get("/customers", verifyToken, (req, res) => {
jwt.verify(req.token, 'justAtest, (err, authData) => {
if (err) {
res.sendStatus(403);
} else {
// execute customers.findAll
}
});
});
Customers is integrated via a requirement
const customers = require("../controllers/customer.controller.js");
The contents are as follows:
exports.findAll = (req, res) => {
Customer.getAll((err, data) => {
if (err)
res.status(500).send({
message:
err.message || "Some error occurred while retrieving customers."
});
else res.send(data);
});
};
Do you have any ideas?
Thank you in advance.
Grettings
Rok
You achieve that using something called "middleware". Explore it since it is very important.
Basically :
app.get("/customers", verifyToken,customers.findAll);
Wherre verify token is a funtion that has 3 parameters: req, res and 3rd one called "next".
So your verify token function would look something like:
(req, res,next) => {
jwt.verify(req.token, 'justAtest, (err, authData) => {
if (err) {
res.sendStatus(403);
} else {
next();
}
});
}
I took it from your snippet. Basically if you want to jump to customeeers.finalAll, just call "next" and it jumps to next function :D.

Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 only on get request page

After building my project. I've noticed I am getting this error after building my application.
Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0
I am only getting this error message only on pages when I am using a get request.
My server code looks something like this
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname, 'build/index.html'), function(err) {
if (err) {
res.status(500).send(err)
}
})
});
app.get('/api/global_rankings', function(request, response){
pool.connect((err, db, done) => {
if(err){
return response.status(400).send(err);
}
else{
db.query("some query", function(err, table){
done();
if(err){
return response.status(400).send(err);
}
else{
response.status(201).send({value: table.rows});
}
});
}
});
});
Ive noticed if i delete the first get request, my second get request works fine. However, I need the first get request or-else I get an GET error message when page is not refreshed.
source: https://tylermcginnis.com/react-router-cannot-get-url-refresh/
Is there any way I can fix this?
Thank you
You are getting a response, and the first character is < which I guarantee is an <html> tag because you are getting HTML back and trying to parse it as JSON.
The reason it works if you remove your first request is because * matches any request, including /api/global_rankings so when you have both methods it matches the * and returns an error page.
Switch the method order and see if it does not work like you want then:
app.get('/api/global_rankings', function(request, response){
pool.connect((err, db, done) => {
if(err){
return response.status(400).send(err);
}
else{
db.query("some query", function(err, table){
done();
if(err){
return response.status(400).send(err);
}
else{
response.status(201).send({value: table.rows});
}
});
}
});
});
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname, 'build/index.html'), function(err) {
if (err) {
res.status(500).send(err)
}
})
});
You have to place the catch-all router /* at the end so it executes only if the route isn't /api/global_rankings:
app.get('/api/global_rankings', function(request, response) { ... }
app.get('/*', function(req, res) { ... });

How to correctly catch errors in node.js/express

Given the example that you are connecting to a mongoDB in js.
mongoClient.connect("mongodb:/localhost/db",
function (err, db){
if (err){
throw err
}
} // some following code
What is the correct to catch errors in an express application so the program carries on running? Currently I have it set up as an if/else. Which does do the trick, it keeps the program running. But it seems a bad way to do it.
mongoClient.connect("mongodb:/localhost/db",
function (err, db){
if (err){
resp.json(err)
console.log(err)
} else {
// some following code
}
}
Is there a better way to catch errors?
new Error([message[, fileName[, lineNumber]]])
this format won't break your server.
but, in case of DATABASE connection errors, server will still not work properly.
use this in server.js or main.js or app.js file it handle all errors and send you error with status code
app.use(function (err, req, res, next) {
console.error(err)
return res.status(500).send({err:err})
});
mongoClient.connect("mongodb:/localhost/db", function (err, db, next){
if (err){
console.log(err);
return next(err);
} else {
// some following code
}
}

Node.js - "TypeError - res.setHeader is not a function"

I'm trying to load JSON from a URL to a variable and send it back to the client's javascript
var getJSON =require('get-json');
app.post('/json', function(req, res) {
getJSON(url, function(err, res){
if(err)
{
console.log(err);
}
else
{
res.setHeader('content-type', 'application/json');
res.send(JSON.stringify({json: res.result}));
}
});
});
Every time I run the code the server says that res.setHeader isn't a function and the rest breaks.
Both post and getJSON callbacks have same res variable name.
Try this:
var getJSON =require('get-json');
app.post('/json', function(req, res) {
getJSON(url, function(err, response){
if(err)
{
console.log(err);
}
else
{
res.setHeader('content-type', 'application/json');
res.send(JSON.stringify({json: response.result}));
}
});
});
for me this was happening when fetching data in a forum i built. i found the fix to this in this blogpost:
https://dev.to/shailesh6363/facing-error-res-setheader-not-a-function-2oc9
i added code according to atul singh in the comments.
changes in app.js
app.use((res, next) => {
....
});
to
app.use((req, res, next) => {
....
});
now the app doesnt crash and it sucessfully fetches and displays the data

Cant set headers after they are sent in Node.js

I am trying to understand how the following code works and the later doesnt.
var Todo = require('./models/database');
function getTodos(res){
Todo.find()
.sort('-created_at')
.exec(function(err, todos) {
if (err) return console.error(err);
// ISSUE HERE
res.json(todos, function(err){
if (err) console.log(err);
}); // return all todos in JSON format
});
};
module.exports = function(app) {
// api ---------------------------------------------------------------------
// get all todos
app.get('/api/todos', function(req, res) {
getTodos(res);
});
// update a todo
app.get('/api/todos/:todo_id/:replacedText', function(req, res) {
console.dir(req.params.todo_id);
console.dir(req.params.replacedText);
Todo.update({ _id : req.params.todo_id},
{$set: {text: req.params.replacedText}},
function(err, todo) {
if (err) res.send(err);
getTodos(res);
});
});
// application -------------------------------------------------------------
app.get('*', function(req, res) {
res.sendfile('./public/index.html'); // load the single view file (angular will handle the page changes on the front-end)
});
};
The above code works. But when i had the code under Todo.find() as:
// ISSUE HERE
res.json(todos); // return all todos in JSON format
This didnt work. I get the following error:
http http.js:689
throw new Error('Can\'t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (http.js:689:11)
at ServerResponse.header (\node_modules\express\lib\response.js:595:10)
at ServerResponse.send (\node_modules\express\lib\response.js:143:12)
at ServerResponse.json (\node_modules\express\lib\response.js:229:15)
at Promise.<anonymous> (\app\routes.js:70:12)
at Promise.<anonymous> (\node_modules\mongoose\node_modules\mpromise\lib\promise.js:177:8)
at Promise.emit (events.js:95:17)
at Promise.emit (\node_modules\mongoose\node_modules\mpromise\lib\promise.js:84:38)
at Promise.fulfill (\node_modules\mongoose\node_modules\mpromise\lib\promise.js:97:20)
at Promise.resolve (\node_modules\mongoose\lib\promise.js:114:23)
Help me figure out, whats happening here.

Categories