Node Server unable to respond to PUT request - node.js

I am making a quite easy CRUD application in MEAN stack.
I have succesfully done all but Update function. Problem is not with request itself but inability of Node server to respond. Request is making changes to database as requested and I even eget a { n: 1, nModified: 0, ok: 1 } response from mongojs.
However, I am unable to send it back to Angular frontend.
I try res.json() but it won't all allow me as it is a not a function? But I am succesfuly doing res.json in create, delete and read. In network tab in developers console, request seems to be pending and after like 30 seconds it throws an error.
No luck with postman either.
How can I send a response to frontend?
// Error handling
const sendError = (err, res) => {
response.status = 501;
response.message = typeof err == 'object' ? err.message : err;
res.status(501).json(response);
};
// Response handling
let response = {
status: 200,
data: [],
message: null
};
// Update log <-- doesn't send response but works
router.put('/update/:id', (req, body, res) => {
console.log("Received UPDATE request");
console.log(req.params.id);
const bodyToUpdate = {
'_id': mongojs.ObjectId(req.params.id),
'week': req.body.week,
'type': req.body.type,
'text': req.body.text,
'days': req.body.days
};
console.log(bodyToUpdate);
db.logs.update({
_id: mongojs.ObjectId(req.params.id)}, bodyToUpdate, (err, res) => {
if (err) return next(err);
response.data = res;
res.json(response);
console.log(response);
});
});
// Delete log <--does work without problems
router.post('/delete/:id', (req, res) => {
console.log("Received DELETE request");
console.log(req.params.id);
db.logs.remove({
_id: mongojs.ObjectId(req.params.id)}, (err, users) => {
if (err) return next(err);
console.log(response);
response.data = users;
res.json(response);
});
});
Service API frontend
deleteLog(id) {
return new Promise((resolve, reject) => {
this._http.post('/api/delete/' + id , id)
.map(res => res.json())
.subscribe(res => {
resolve(res);
console.log(res);
}, (err) => {
reject(err);
});
});
}
updateLog(logToUpdate) {
return new Promise((resolve, reject) => {
this._http.put('/api/update/' + logToUpdate._id, logToUpdate)
.map(res => res.json())
.subscribe(res => {
resolve(res);
// console.log(res);
}, (err) => {
reject(err);
});
});
}

As #JithinSebastian correctly pointed out - I should not have 3 arguments in put request. I also had to change name of callbacks in mongo update function because I already used res in router function callback.
// Update log
router.put('/update/:id', (req, res) => {
console.log("Received UPDATE request");
console.log(req.body);
const bodyToUpdate = {
'_id': mongojs.ObjectId(req.params.id),
'week': req.body.week,
'type': req.body.type,
'text': req.body.text,
'days': req.body.days
};
db.logs.update({
_id: mongojs.ObjectId(req.params.id)
}, bodyToUpdate, (err, logs) => {
if (err) return next(err);
response.data = logs;
res.json(response);
console.log(response);
});
});

Related

express-session with mongo-store - Headers already sent in req.session.save() callback

im using express-session with a mongo-store.
However, in my authentication process i call req.session.save() after the user is authenticated successfully. But when i try to send a response to the client i get the message Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
When i send the response before i call req.session.save() and not inside the callback, its working.
This is what my code snippet looks like.
// res.json({ data: 'hello world' }); //This is working...
req.session.save((err) => {
if (err) {
console.log('Error saving session: ', err);
} else {
// res.json({ data: 'Hello CB' }); //Headers already sent
}
});
I also can see that the session is saved in my mongoDb.
I couldn't find anything which tells me, that req.session.save() is sending some response to the client.
Why are the headers already sent in the callback function of req.session.save() ?
Updated full Requestfunction:
const Create = async (req, res) => {
const { code } = req.body;
await Authenticate(code)
.then((user) => {
//Check if User already exists in database
UserModel.getUser(user.id)
.then((resDB) => {
if (resDB === null) {
console.log('User not found');
//User dont exists, create it
UserModel.createUser({
...
})
.then((is_saved) => {
if (is_saved) {
res.json(user);
res.end();
}
})
} else {
req.session.regenerate((err) => {
req.session.value = "somevalue";
});
req.session.save((err) => {
if (err) {
console.log('Error saving session: ', err);
} else {
// res.json({ cookie: req.session });
res.json({ data: 'Hello from CB' });
res.end();
}
});
}
})
.catch((err) => {
console.log('User Create or Login error: ', err);
res.end();
})
})
.catch((err) => {
console.log('Authentication error', err);
res.end();
});
}
Seems like you are missing async and await. Can you share complete method code?
const saveInSession = async (req, res, next) => {
const getData = await req.body; //just an example
req.session.save((err) => {
if (err) {
console.log('Error saving session: ', err);
} else {
// res.json({ data: 'Hello CB' }); //Headers already sent
}
});
};

Axios.get is not returning anything in nodeJS,Express

I have a problem with .get request.
Somehow it is not returning anything? (GET http://localhost:8080/admin net::ERR_EMPTY_RESPONSE)
Any suggestions?
Get Route,With this I'm trying to filter all items by their username:
app.get("/:username", verify, (req, res) => {
console.log("Welcome to roffys server");
Todo.find({ username: req.params.username }).then((err, todo) => {
if (err) {
console.log("Error retrieving todos");
} else {
res.json(todo);
}
});
});
Verify function,here I'm verifying my auth-token,I console logged it and it is working fine:
const jwt = require("jsonwebtoken");
module.exports = function (req, res, next) {
const token = req.header("auth-token");
console.log("-----token", token);
if (!token) return res.status(401).send("Access Denied");
try {
const verified = jwt.verify(token, "secretkey");
req.user = verified;
} catch (err) {
res.status(400).send("Invalid token");
next();
}
};
FE Side with ReactJS :
componentDidMount() {
const { getAll, setPageCount } = this.props.actions;
axios
.get(`http://localhost:8080/${localStorage.getItem("username")}`, {
headers: {
"auth-token": localStorage.getItem("auth-token"),
},
})
.then((res) => {
getAll(res.data);
setPageCount();
console.log("--------res.data", res.data);
})
.catch((err) => {
console.log("err", err);
});
}
app.get("/:username", verify, (req, res, next) => {
console.log("Welcome to roffys server");
Todo.find({ username: req.params.username }).then((err, todo) => {
if (err) {
console.log("Error retrieving todos");
return next(err);
} else {
res.json(todo);
}
});
});
try to add next to your handler and call it when you receive an error.

Subscribe method does not work in angular

product-operations.component.ts
deleteProduct() {
this.productsService.delete_product(this.deleteID).subscribe((res: any) => {
console.log("helloooooo");
});
};
product.service.ts
delete_product(id) {
return this.http.delete("http://localhost:3000/delete_product/" + id);
}
backend
exports.deleteProduct = (req, res, next) => {
const id = req.param("id");
Product.deleteOne({ _id: id })
.then(() => {
console.log("deleted");
})
.catch(err => {
console.log(err);
});
};
Problem:
In the above codes, the deleteProduct function in product-operations.component.ts doesn't work properly. More precisely, it does the removal. But after doing the uninstall, subscribe doesn't run its contents. This prevents my instant update after deletion. How can I solve this?
Try to send a response back from the server.
exports.deleteProduct = (req, res, next) => {
const id = req.param("id");
Product.deleteOne({ _id: id })
.then(() => {
res.send({}) // or res.send({id: id})
console.log("deleted");
})
.catch(err => {
res.status(500)
res.send({error: err})
console.log(err);
});
};

ERR_HTTP_HEADERS_SENT in Nodejs Server (AWS)

I'm asking again with this code provided Please Help Thank you. I am calling this API with Firebase function from Android using okhttp3, here the code below. I already subscribed to a plan in firebase to call external API
Firebase Cloud Function Code
exports.CustomerProfile = functions.https.onRequest((req, res) => {
const options = {
method: "POST",
uri: "http://3.xxxx.xx.xx2:3000/api/customers/profile",
formData: {
session_token: req.body.session_token
},
headers: {
"content-type": "application/x-www-form-urlencoded",
"x-auth-token": "xxxxxxE"
},
resolveWithFullResponse: true,
json: true,
simple: false
};
rp(options)
.then(function(response) {
res.send(response.body);
})
.catch(function(err) {
res.send(err);
});
});
API CODE
router.post("/profile", async (req, res) =>{
const customers = new Customers();
var data = req.body;
var token = req.body.session_token;
customers.findBySessionToken(token, (err, result) => {
if (!err) {
if(result[0].provider === 'gmail'){
var gmail = result[0].access;
customers.findByGmail(gmail, (err, result) => {
res.status(200).send(result);
});
}else if(result[0].provider === 'facebook') {
var facebook = result[0].access;
customers.findByFb(facebook, (err, result) => {
res.status(200).send(result);
});
}else if(result[0].provider === 'mobile') {
var mobile = result[0].access;
customers.findByMobile(mobile, (err, result) => {
res.status(200).send(result);
});
}
} else {
if (err.code === "ER_SIGNAL_EXCEPTION") {
res.status(400).send([{ message: err.sqlMessage }]);
} else {
res.status(400).send(err);
}
}
});
});
this means that you have already sent a response res.send... somewhere else , you cant do more than one response for a request.

Accessing a passed Object with Express and Axios

In the client side I have :
handleChangeSave(values, id) {
axios.post('/api/users/change' + id, JSON.stringify(values))
.then(resp => {
console.log(resp.data);
})
.catch(function (error) {
console.log(error);
});
}
On the server side I am trying to query for the object and it is coming back empty when it is really not.
router.post('/users/change:id', (req, res) => {
User.findById({ '_id': req.params.id }, (err, user) => {
if(err) return res.status(500).send(err);
let Values = req.query;
console.log(Values); // returns {}
})
});

Resources