Node Js findByIdAndUpdate function not updating in db - javascript

Im updating products based on its id in nodejs by creating API and calling them in angular 2 services.
routes/products.js
router.post('/:id', function(req, res, next) {
Products.findByIdAndUpdate(req.params.id, req.body, function (err, post) {
if(err){
res.json({success: false, msg:'Failed updating products'});
} else {
res.json({success: true, msg:'success updating products'});
}
});
});
This is how im passing in postman: POST request
{
"id":"596df0ffcb429a586ef6c0bf",
"category_id": "596ddb165314d15618795826",
"product_name":"Laysssss masala",
"product_price":5,
"product_image":"image1ddd",
"product_desc":"Yummyddsd",
"product_status":"Activedddd"
}
Products seem to be saved in DB.
The same when i call in services under angular and try in browser, i get "Product updated successfully" in broswer , but not reflecting in DB.
component.ts
onSaveConfirm(event) {
if (window.confirm('Are you sure you want to save?')) {
// var prodId = event.newData['_id']
//console.log(event.newData)
this.productService.productUpdate(event.newData).subscribe(data => {
if (data.success) {
console.log('Edited success')
this.flashMessage.show('Product updated successfully', { cssClass: 'alert-success', timeout: 3000 });
this.router.navigate(['/category-items']);
} else {
console.log('failure edited...')
this.flashMessage.show('Something went wrong', { cssClass: 'alert-danger', timeout: 3000 });
this.router.navigate(['/category-items']);
}
});
event.confirm.resolve(event.newData);
} else {
event.confirm.reject();
}
}
product.service.ts
productUpdate(products) {
var prodId = products['_id'];
console.log(products)
let prodUrl = "http://localhost:8080/products/" + prodId
let headers = new Headers();
headers.append('Content-Type', 'application/json');
let prodIdObj = JSON.stringify({ products: products })
return this.http.post(prodUrl, prodIdObj, { headers: headers })
.map((response: Response) => response.json())
.do(data => JSON.stringify(data))
.catch(this.handleError);
}

Maybe your problem here:
In product.service.ts:
productUpdate(products) {
//skipped
let prodUrl = "http://localhost:8080/products/" + prodId
//skipped
}
and products.js
router.post('/:id', function(req, res, next) {
Products.findByIdAndUpdate(req.params.id, req.body, function (err, post) {
if(err){
res.json({success: false, msg:'Failed updating products'});
} else {
res.json({success: true, msg:'success updating products'});
}
});
});
change it to:
router.post('products/:id', function(req, res, next) {
//do something
});

Related

UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the clien

I get error: "UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client",
guessing that the problem is with promises, but I don't understand how to fix it.
How do I fix my code to avoid this error, but keep the logic and work with the database?
router.post("/addNote", (req, res) => {
let currentTime = new Date();
currentTime.setUTCHours(currentTime.getUTCHours() + 3);
const post = new PostModel({
title: req.body.inputHeader,
text: req.body.inputText,
author: req.body.author,
createdAt: currentTime
});
post.save().then(() => {
res.json({status: "saved"});
})});
router.get("/getNotes", (req, res) => {
PostModel.find().sort({createdAt: 'descending'}).then( (err, notes) => {
if (err)
res.json(err);
res.json(notes);
});
});
router.delete("/deleteNote/:id", (req, res) => {
PostModel.deleteOne(
{
_id: req.params.id
}
).then((notes) => {
if (notes)
res.json({status: "deleted"});
res.json({status: "error while deleting"});
});
});
router.put("/updateNote/:id", (req, res) => {
PostModel.findByIdAndUpdate(
req.params.id,
{
$set: req.body
},
err => {
if (err)
res.send(err);
res.send({status: "updated"})
}
).then((notes) => {
if (notes)
res.json({status: "update"});
res.json({status: "error while updating"});
});
});
router.get("/getNote", (req, res) => {
PostModel.findOne({ _id: req.params.id}).then(post => {
if (!post){
res.send({error: "not found"});
} else {
res.json(post)
}
});
});
router.post("/authorize", (req, res) => {
// bcrypt.hash ("", saltRounds, (err, hash) => {
// console.log(hash);
// });
let resultAuthorization = false;
if (req.body.login === authorization.login) {
resultAuthorization = bcrypt.compareSync(req.body.password, authorization.password);
}
if (resultAuthorization)
res.json({statusAuthorization: "correct"});
res.json({statusAuthorization: "incorrect"});
});
module.exports = router;
The problem is that you are calling res.json several times in one handler. When calling it a second time a response has already been sent so you can not send another response.
As tkausl already pointed out you are missing elses so that res.json is being called once.
You need to change your handlers similar to the /getNote handler.
The handler for the endpoint deleteNode/:id for example has to be changed to this:
router.delete("/deleteNote/:id", (req, res) => {
PostModel.deleteOne(
{
_id: req.params.id
}
).then((notes) => {
if (notes)
res.json({status: "deleted"});
else
res.json({status: "error while deleting"});
});
});
This else also needs to be added in /getNotes and /authorize.
The reason is you're trying to send a response more than once. Once the response is returned, if the program sends a response again, this error occurs.
The reason for the problem is that you do not return the current function after the if condition.
Let me explain with some codes
router.get("/getNotes", (req, res) => {
PostModel.find().sort({createdAt: 'descending'}).then( (err, notes) => {
if (err) {
res.json(err);
console.log('We encountered an error and sent the error as a response. But our function still continue...');
}
res.json(notes);
console.log('We tried to sent successfull response but function still continue');
});
});
So after the response, you should end the function or make sure that you do not call any other response function in the ongoing code stream/flow.
Lets fix your code.
router.get("/getNotes", (req, res) => {
PostModel.find().sort({createdAt: 'descending'}).then( (err, notes) => {
if (err) {
return res.json(err);
// It is not will be continued because the function returned with response.
}
return res.json(notes);
console.log('No console output')// It is will not be called because function returned.
});
});

Request Aborted on axios.get reactJS

I'm trying to make get request via token from local storage but it is giving me Request aborted error.
Here is My nodeJS code :
//Read
app.get('/:username',verify, (req, res) => {
console.log('Welcome to roffys server')
Todo.find({'username' : req.params.username})
.exec((err, todo) => {
if (err) {
console.log('Error retrieving todos')
} else {
res.json(todo)
}
})
})
Here is the Verify function :
const jwt = require('jsonwebtoken')
module.exports = function (req,res,next){
const token = req.header('Authentication')
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()
}
And here is my FE on ReactJS component:
componentDidMount() {
axios
.get(`http://localhost:8080/${localStorage.getItem('username')}`,{
headers : {
Authentication : localStorage.getItem('token')
}
})
.then((res) => {
this.setState({todos: res.data})
this.setPageCount()
})
.catch((err) => {
console.log("err", err);
});
}
None of yow methods return anything.
componentDidMout () {
return axios.get(url, config)
.then (res=> this.setState(myProp: res.data});
......
Back
var verify = require(“./path/to verify”);
//Read
app.get('/:username',verify, (req, res) => {
return Todo.find({'username' : req.params.username})
.exec()
.then(todo=> res.json(todo))
.catch(console.log);
})

I can't insert data to my database (mysql)

I'm learning now MySQL and I have a some problem. I tried to make a post request to my db::
My code from client side:
async function sendValues() {
const settings = {
method: 'post',
headers: { "Content-Type": "application/json" },
body: JSON.stringify(product)
}
try {
const fetchResponse = await fetch('http://localhost:9001/products', settings);
const data = await fetchResponse.json();
console.log(data) // what the user send
} catch (err) {
return err
}
}
My code from server side:
router.post('/', (req, res) => {
const { c_id, p_name, p_price } = req.body
const q =
`
INSERT INTO products (c_id,p_name,p_price)
VALUES("${c_id}", "${p_name}" , "${p_price}")
`;
con.query(q, (err, result, fields) => {
if (err) throw err;
res.json(result)
});
});
There are two possible mistakes:
1.check the connection between client and server. as mentioned above.
2.check the table name, data type of attributes, name of attributes you are providing.
The rest endpoint is / and you are calling products change your backend code as below.
router.post('/products', (req, res) => {
const { c_id, p_name, p_price } = req.body
const q =
`
INSERT INTO products (c_id,p_name,p_price)
VALUES("${c_id}", "${p_name}" , "${p_price}")
`;
con.query(q, (err, result, fields) => {
if (err) throw err;
res.json(result)
});
});

Data does not update in view

I am creating an update function in my ionic 4 frontend which has a form to update user info. When I try to change the name, for example, it is updated in the database but is not displayed in the view through interpolation unless I logout and log back in. Here is my update method in the frontend.
updateInfo() {
if (!this.updateForm.valid) {
this.invalidUpdate();
} else {
if (!(this.name === "")) {
var nameObj = {
name: this.name
};
this._userService.updateName(nameObj).subscribe(
data => {
console.log(data);
this.getUserNamePoints();
},
error => {
this.updateFail();
}
);
}
};
this.getUserNamePoints();
}
}
And here is the method updateName(name) in the service
updateName(name) {
var headers = new Headers();
headers.append(
"Authorization",
"Bearer " + this._authService.getAuthorizationToken()
);
headers.append("Content-Type", "application/json");
return this.http
.post(environment.apiUrl + "/user/updateName", name, {
headers
})
.map(res => res.json());
}
This is the method getUserNamePoints() which is also called in the constructor:
getUserNamePoints() {
this._authService.getPoints().subscribe((res: any) => {
this.current = res.data;
this.clientName = res.name;
});
}
And here is the interpolation I am performing:
<h2>
<ion-text color="secondary" style="font-weight:bold">
Hello, {{ clientName }}!</ion-text
>
</h2>
This is my backend method:
module.exports.updateName = function(req, res, next) {
User.findByIdAndUpdate(
req.decodedToken.user._id,
{
$set: req.body
},
{ new: true }
).exec(function(err, updatedUser) {
if (err) {
return next(err);
}
res.status(200).json({
err: null,
msg: "Name was updated successfully.",
data: req.decodedToken.user.name
});
});
};
I think the problem is in your backend. I can see that you are sending the data from the decoded token and the token is encoded when you login, so it does not have the updated data.
res.status(200).json({
err: null,
msg: "Name was updated successfully.",
data: req.decodedToken.user.name
});
Can you show me how are you retrieving the data of the user from your backend when you call the method "getUserNamePoints();" ? Are you looking for the user data in your database or in the decoded token?

error in getting the response, if nodejs server send response after some delay

I am trying to upload the image, and then nodeJS server send the path of that image folder back as a response.
But When I sending the response after performing some task, nothing happening on angular-side.
this is my component.ts file.
uploadImage() {
const formData = new FormData();
formData.append('photo', this.image);
const obj$ = this.userService.uploadData(formData);
obj$.subscribe(data => {
console.log(data); //// nothing happening.
if (data.success) {
this.uploadForm.patchValue({
document: data.url
});
}
});
}
and my service.ts
uploadData (uploadImage) {
return this.http.post<UploadPhoto>('/user/upload', uploadImage);
}
and my app.js
router.post('/upload' ,upload.single('photo'), (req,res) => {
console.log(req.file);
const body = req.file;
cloudinary.uploader.upload(body.path, (err, result) => {
if (err) {
console.log(err);
return;
}
console.log(result);
res.status(200).json({
url: result.url,
success: true
});
});
});
But when I am sending response without performing any task, it works fine like
router.post('/upload' ,upload.single('photo'), (req,res) => {
console.log(req.file);
const body = req.file;
res.status(200).json({
url: 'hello',
success: true
})
});
I don't know why is this happening.
Please someone help me.
When an error occurs in your uploader you're returning the error to the console and then ending execution. If there is an error in the asynchronous method you must pass it to the next() function so that express can handle it.
router.post('/upload' ,upload.single('photo'), (req,res, next) => {
console.log(req.file);
const body = req.file;
cloudinary.uploader.upload(body.path, (err, result) => {
if (err) {
console.log(err);
next(err);
}
else {
console.log(result);
res.status(200).json({ url: result.url, success: true });
}
});
});

Categories

Resources