0

I'm working with a MMEAN stack with Mongoose and MongoDB. I would like to test if the collection Foo is empty or not, but it involves a Mongoose find() function with a callback. I'm unfamiliar with callbacks, so I would like to know how to get a piece of information from inside a callback out into its parent function.

This is the logic I must follow for addFoo: 1. check if the Foo collection is empty 2. If Foo is empty, save the new Foo document 3. If Foo is not empty, do not save the new Foo document

I'm calling the save method, addFoo(), from routes/index.js.

// routes/index.js
router.post('/foo', function(req, res, next){
  var foo = new Foo(req.body);
  foo.addFoo(function(err, bid){
    if(err){ return next(err); }
    res.json(foo);
  });
});

// models/Foo.js

var mongoose = require('mongoose');
var FooSchema = new mongoose.Schema({
  creator: String
});
mongoose.model('Foo', FooSchema);

FooSchema.methods.addFoo = function(cb){

  // finds all documents of Foo into the "results" array
  this.model("Foo").find(function(err, results){
    if (err){return err;}
    // if the Foo results array is empty
    if (results.length == 0){
      // HOW DO I LET addFOO() KNOW THAT THE ARRAY IS EMPTY?
      // somehow pass the boolean out to addFoo()
    }
  });

  // IF Empty
  // this.save(cb);

}
Melissa
  • 1,236
  • 5
  • 12
  • 29

2 Answers2

1

Short answer: You don't.

The callback gets executed after the addFoo function ends. You'd basically put the rest of your function inside the callback.

Since you need access to this, you can bind it to a variable via var self = this; and then use self inside the callback.

Another option is to use promises and a denodeify function that turns a callback requesting function into a Promise returning function.

Havvy
  • 1,471
  • 14
  • 27
1

This will work as follows ...

FooSchema.methods.addFoo = function(cb){
  var that = this;
  this.model("Foo").find(function(err, results){
    if (err){return err;}
    // if the Foo results array is empty
    if (results.length == 0){
      that.save(cb);
    }
  });
}

However if you want to pass it to parent as per your actual requirement, then you can try it as below ....

 FooSchema.methods.addFoo = function(cb){
      var that = this;
      this.model("Foo").find(function(err, results){
        if (err){return err;}
        // if the Foo results array is empty

          that.commit(!results.length);//Calling a parent function from inside callback function

      });

       function commit(doCommit){
         if(doCommit) {  
            that.save(cb);
         }
       }
    }
Sridhar Gudimela
  • 564
  • 8
  • 14