I'm trying to toggle and update a boolean value in database whenever a button is clicked..
My HTML:
<form action="/browse/<%= book._id %>/sold" method="GET">
<button type="submit"> Mark As Sold </button>
</form>
Schema:
var bookSchema = new mongoose.Schema({
title: String,
description: String,
sold: { type:Boolean, default: false }
});
I've tried to use this on the .get route :
Book.findByIdAndUpdate(req.params.id, {$set: {sold: !sold} }, function(err, book){
....
}
but it doesnt work.. (sold is undefined)
I'm new to express and mongoose and searched on google a lot but couldnt find a solution. Please help. is there any other way to solve this?
I'm trying to toggle and update a boolean value in database whenever a button is clicked..
My HTML:
<form action="/browse/<%= book._id %>/sold" method="GET">
<button type="submit"> Mark As Sold </button>
</form>
Schema:
var bookSchema = new mongoose.Schema({
title: String,
description: String,
sold: { type:Boolean, default: false }
});
I've tried to use this on the .get route :
Book.findByIdAndUpdate(req.params.id, {$set: {sold: !sold} }, function(err, book){
....
}
but it doesnt work.. (sold is undefined)
I'm new to express and mongoose and searched on google a lot but couldnt find a solution. Please help. is there any other way to solve this?
Share Improve this question asked Jul 14, 2016 at 19:36 Bhoomika ChauhanBhoomika Chauhan 1531 gold badge3 silver badges7 bronze badges 6- can you show how and where are you declaring sold variable , it may be a scope problem. – rresol Commented Jul 14, 2016 at 19:42
- @rresol actually i didnt declare it anywhere.. i though it will toggle the sold value thats in the database. just realized i am wrong. is there any way to reference the value which is already in database? – Bhoomika Chauhan Commented Jul 14, 2016 at 19:45
- What exactly do you want to do ? – rresol Commented Jul 14, 2016 at 19:48
- @rresol when the user clicks the button sold becomes true, on clicking it again sold becomes false ..and so on – Bhoomika Chauhan Commented Jul 14, 2016 at 19:52
- When the button will be clicked then it must be emitting some signal or some request , and since you want to update sold only when the button is clicked, add a callback which will be called if the event occurs and pass {sold: true} in $set. – rresol Commented Jul 14, 2016 at 19:56
5 Answers
Reset to default 9The method you are using will not work. You are referencing an undeclared
variable sold
in this snip: {sold: !sold}
. If anything, you'd want to do {sold: !this.sold}
, but this
within a findById
is a query and not the model. You would have to use findById
for the book you want, update it manually (book.sold = !book.sold
) then save
it.
You could create a static method on your model to accomplish all this.
It would look something like
bookSchema.statics.findByIdAndToggleSold = function(id, callback){
// Your code to find, then update here.
}
There's sadly no way to directly invert a record in a single operation - if you want to operate on just booleans, you need to find, mutate, then save again as Austin says.
If you can change your data slightly though, we can actually approximate this using integers. If we use integers, we can use bitwise operations to do this, e.g.
Book.insert({myBoolVal: 0}); // Insert as false
Book.findAndUpdate(req.params.id, {$bit: {myBoolVal: {xor: 1}}}); // 0 xor 1 = 1; 1 xor 1 = 0
Book.find({myBoolVal: 0}); // false
Book.find({myBoolVal: 1}); // true
In this case, your Mongoose model must specify myBoolVal
to be an integer. This requires the Int32
package, as of this answer: Mongoose ODM: NumberInt is not defined. For example:
var NumberInt = require("mongoose-int32");
var bookSchema = new mongoose.Schema({
title: String,
description: String,
sold: { NumberInt, default: 0}
});
You could just update the document in this convenient way :
Book.findOne({ _id: req.params.id }, function(err, book) {
book.sold = !book.sold;
book.save(function(err, updatedBook) {
...
});
});
You can base it on $mod
judging odd and even numbers
$mod : [2,0]
$mod : [2,1]
var bookSchema = new mongoose.Schema({
title: String,
description: String,
sold: { type:Number, default: 0 }
});
bookSchema.findOneAndUpdate({_id:req.params.id},{$inc:{sold: 1}});
bookSchema.findOne({_id:req.params.id, sold:{$mod : [2,0]}})
app.put("/todo/update/:id", function (req, res) {
Todo.findById(req.params.id, function (err, todo) {
todo.done = !todo.done;
todo.save(function (err, updatedTodo) {
if (err) {
console.log(err);
} else {
res.redirect("/")
}
})
})
});
This is an example I used using the express, mongoose and nodejs.
Here is an example of my model:
const todoSchema = new mongoose.Schema({
text: {
type: String,
required: true
},
done: {
type: Boolean,
default: false
}
});
const Todo = mongoose.model('Todo', todoSchema);
Other Dependencies:
- Method Override.
- Body Parser.