最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Mongoose findByIdAndUpdate method to toggle and update a Boolean value in database - Stack Overflow

programmeradmin4浏览0评论

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
 |  Show 1 more comment

5 Answers 5

Reset to default 9

The 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.
发布评论

评论列表(0)

  1. 暂无评论