2

Given is an array with book objects, where each status has to be updated:

var books = [ 
              { id: '58b2e58', status: 'pending' },
              { id: '5903703', status: 'pending' } 
                ]

var status = {status: 'accepted'}

I tried this:

Book.update(books, status).exec(function afterwards(err, updatedbooks) {
            if (err) {
                res.json(err)
                }
            console.log("updatedbooks:", updatedbooks);
});

but the 'updatedbooks' log is empty. When checking in mongodb, the books are there, I can find them with Book.find(books);

As here mentioned this here works fine, but I want to have beside the ID's also the status=="pending" in the WHERE criteria.

Community
  • 1
  • 1
Suisse
  • 3,467
  • 5
  • 36
  • 59
  • what do you mean with "empty"? can you provide the log please? – Ronin Apr 28 '17 at 18:33
  • Sir, please... console.log("updatedbooks:", updatedbooks); gives "updatedbooks: [ ]" – Suisse Apr 28 '17 at 18:36
  • you are aware that this operation isn't idempotent, right? could it be that you ran the function before and already changed the objects to the desired state , then added the console.log and ran the function again which wouldn't match and therefore update anything? This would obviously return any objects as part of the `Sucessfully Updated Records` callback parameter. Happy sabbath! – Ronin Apr 28 '17 at 18:41
  • Sir, no thats not true. because the console.log is called in the function called "afterwards()" that mean after the update is done. bro do you even manuals? Happy sabbath. – Suisse Apr 28 '17 at 18:46
  • YES but if you already updated all status fields of your books then it wont update anything when running the function again. – Ronin Apr 28 '17 at 18:48
  • Sir, I don't want to call you "sir" furthermore. The discussion ends here. The books are NOT updated, accept it. Sir. – Suisse Apr 28 '17 at 18:51

2 Answers2

2

please try this.

var bookId= ['1','3'];
var status = {status: 'accepted'}
Book.update({id:bookId, status: 'pending'}, status).exec(function afterwards(err, updatedbooks) {
        if (err) {
            console.log('error in update\n'+err);
            res.json(err)
            }
        else{
            console.log("updatedbooks:", updatedbooks);
        }
});

This should work. Also, if you are getting an error, it will give you an idea about what error you are getting.

Foramkumar Parekh
  • 421
  • 1
  • 6
  • 26
  • 1
    Any idea how can I update the status of book id 1 to accepted and book id 3 to rejected? I tried the following but both the records are being updated with the status of accepted. var status = {status: ['accepted', 'rejected']} Book.update({id: bookId, status: 'pending'}, status).exec((err, updated) => {}) – 99darshan Nov 12 '17 at 04:38
  • 1
    @99darshan For updating multiple records with different values you would either use the underlying database manager and its native methods OR create a Promise.all([])... collection where each promise is a separate Book.update() submission. There is no batch update method with different values in Sails. – nopuck4you Aug 08 '18 at 06:43
  • for that first use Book.find. Inside that, iterate over the data, update the required data with the desired values and then use the data.save method to update. Save will automatically update the content. – Foramkumar Parekh Oct 22 '18 at 07:07
0

If someone has the correct answer, don't wait. I found a workaround:

The find() function can take criteria like this:

var bookCriteria = [ 
              { id: '1', status: 'pending' },
              { id: '3', status: 'pending' } 
                ]

But the update() function only works with an array with ids:

var bookCriteria = [ '1','3']

So lets first search for books which fulfill our criterias and then take those books and update them.

      Book.find(bookCriteria).exec(function (err, booksFounded) {
            //booksFounded is an array with book objects, with status = 'pending'
            //but we need an array with booksFounded ids as strings

              var bookIDs = booksFounded.map( book => book.id}); //['1','3']

            //now update:

                Book.update(bookIDs , {status:'accepted'}).exec(function afterwards(err, updatedbooks) {
                if (err) {
                    res.json(err)
                    }
                console.log("updatedbooks:", updatedbooks);
                });

   })

Do you have a better solution? With my solution it needs 2 DB transactions, but it works.

Suisse
  • 3,467
  • 5
  • 36
  • 59
  • Here (`var bookIDs = booksFounded.map( book => book.id});`), you can use `bookCriteria` in place of `booksFounded` and get rid of `find` call. Does this work for you? – Sangharsh May 01 '17 at 08:01
  • No, because like I wrote, I need to update only the books which have the `status:pending`. The `find()` function can take the `bookCriteria`, but the `update()` function can't. Thats why, you first have to 'filter' the books which have those `ID`'s + are `pending`. And after that update the new founded books which fulfill the `bookCriteria`. - who is downvoting the answer, without having a better answer?? – Suisse May 01 '17 at 10:51