0

I query author data from a MongoDB via Mongoose (MEAN environment). The author data also contains an array of books that the author wrote (-> results.books). Once received, I'd like to iterate through this array of books and check for certain values. This is my code so far.

return Author.findOne({_id: req.user._id}, '-username').execAsync()
.then(function(results) {

return Promise.each(results.books) //this line causes TypeError rejection
}).then(function(book){     
   console.log('book:'+book); // test output
   if(book==='whatever‘){
      //do foo
   }  
}).catch(function(err){
    console.log('Error: '+err);
});

Unfortunately I can't get it to work as it keeps giving me a rejection TypeError for the line marked above. I tried to apply this solution here (Bluebird Promisfy.each, with for-loops and if-statements?) but it wouldn't work out as it also seems to be a different kind of problem.

Community
  • 1
  • 1
Igor P.
  • 1,407
  • 2
  • 20
  • 34
  • Does findOne really return an array? I don't know it - but guess that you get an object back, but `each` expects an array – baao Feb 23 '16 at 00:42
  • Per [doc](http://mongoosejs.com/docs/queries.html), a potentially-null single document should returned by `findOne` – zangw Feb 23 '16 at 01:02

1 Answers1

2

Bluebird's Promise.each() takes an iterable AND a iterator callback function that will be called for each item in the iterable. You are not passing the callback function. The .then() handler after Promise.each() is called when the entire iteration is done. It looks like you're expecting that to be the iterator - that's not the case.

Bluebird doc for Promise.each() is here.

I'm not sure exactly what you're trying to accomplish, but perhaps this is what you want:

return Author.findOne({_id: req.user._id}, 'username').execAsync()
   .then(function (results) {
        return Promise.each(results.books, function(book) {
            console.log('book:' + book); // test output
            if (book === 'whatever‘) {
               //do foo
            }
        });
    }).then(function() {
        // Promise.each() is done here
    }).catch(function (err) {
        console.log('Error: ' + err);
    });
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • that seems to work. Thanks! I guess, I need to get back and do a bit more of reading on promises to get a deeper understanding, still struggling with basic issues - bummer. Thanks again. – Igor P. Feb 23 '16 at 20:58
  • One more thing: is there any way to quit the .each() loop early (before end of array is reached) except by throwing an exception? Something comparable to 'break;' in while loops or a plain 'return;' counterpart? Couldn't find anything in the Bluebird doc. – Igor P. Feb 23 '16 at 22:09
  • @IgorP. - I'm not aware of any way to quit early other than throwing or returning a rejected promise - both of which will cause the returned promise to be rejected. – jfriend00 Feb 23 '16 at 22:10