3

I follow a MCV approach to develop my application. I encounter a problem that I dont know how the arguments are passed to the callback function.

animal.js (model)

var mongoose = require('mongoose')
, Schema = mongoose.Schema

var animalSchema = new Schema({ name: String, type: String });
animalSchema.statics = {
     list: function(cb) {
         this.find().exec(cb)
     }
}
mongoose.model('Animal', animalSchema)

animals.js (controller)

var mongoose = require('mongoose')
, Animal = mongoose.model('Animal')

exports.index = function(req, res) {
    Animal.list(function(err, animals) {
        if (err) return res.render('500')
        console.log(animals)
    }
}

Here comes my question: Why can the "list" in the model just execute callback without passing any argument? Where do the err and animals come from actually?

I think I may miss some concepts related to callback in node.js and mongoose. Thanks a lot if you can provide some explanation or point me to some materials.

1 Answer 1

2

The function list wants to have a callback function passed.

So you pass a callback function.

this.find().exec(cb) wants a callback function too, so we pass the callback we got from the list function.

The execute function then calls the callback (executes it) with the parameters err and the object it received, in this case animals.

Inside of the list function happens something like return callback(err, objects) what is finally calling the callback function.

The callback function you passed now has got two parameters. These are err and animals

The key is : The callback function is passed as a parameter, but is never called until it is called by the exec. This function is calling it with parameters which are mapped to err and animals

EDIT:

As it seams unclear i will do a short example:

var exec = function (callback) {
    // Here happens a asynchronous query (not in this case, but a database would be)
    var error = null;
    var result = "I am an elephant from the database";
    return callback(error, result);
};

var link = function (callback) {
    // Passing the callback to another function 
    exec(callback);
};

link(function (err, animals) {
    if (!err) {
        alert(animals);
    }
});

Can be found as a fiddle here : http://jsfiddle.net/yJWmy/

Sign up to request clarification or add additional context in comments.

7 Comments

Thanks for answer first. I understand the first part of your answer. But I am confused with the second part: The list function never declare a variable called "animals". How does it map the object it received from the database to "animals"?
it doesnt have to know the name of the object, it simply calls callback(err, objects)which is mapped to function (err, animals) . So objects gets mapped to animals
Maybe you missed that callback is passed to the list function too, the execution happens inside of the list function, you can't see here
Am I correct to think this way?: when the "list" function inside "animal.js" runs this line this.find().exec(cb), this.find() returns two variables "err" and "objects" and calls cb(err, objects). So it maps to function(XXX, YYY) which is function(err, animals) in this case.
It causes my confusion because from the API doc of mongoose Mongoose exec API , it does not mention how err and objects are passed to the callback function
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.