Question

I have the code below:

var mongoose = require('mongoose');
var Q = require("q")
mongoose.connect("mongodb://localhost/testdb");

var Schema = mongoose.Schema;
var employeeSchema = new Schema({
    name:String
})
var Employee = mongoose.model('Employee', employeeSchema);

var departmentSchema = new Schema({
    name:String
})

var Department = mongoose.model('Department', departmentSchema);

var employee = new Employee();
employee.name = "T.Smith";
var dept = new Department();
dept.name = "Sales";


Q.spread([
    Q.nfcall(employee.save.bind(employee)),
    Q.nfcall(dept.save.bind(dept))
],function(emp,dept){
    console.log(JSON.stringify(emp));
    console.log(JSON.stringify(dept));
    mongoose.disconnect();
})

The log statements will yield the results below:

[{"__v":0,"name":"T.Smith","_id":"5358f3c53cd354bc70fe619f"},1] [{"__v":0,"name":"Sales","_id":"5358f3c53cd354bc70fe61a0"},1]

Why are the results an array instead of a single object?

I get the same if i replace the last block of code with this block:

Q.all([
    Q.nfcall(employee.save.bind(employee)),
    Q.nfcall(dept.save.bind(dept))
]).spread(function(emp,dept){
    console.log(JSON.stringify(emp));
    console.log(JSON.stringify(dept));
    mongoose.disconnect();
})

By the way, which block is recommended?

Was it helpful?

Solution

The save callback signature is function(err, result, numberAffected) which doesn't conform to node callback convention. nfcall expects a node callback signature, which is function(err, result). To avoid loss of information, the promise returned by nfcall resolves to [result, numberAffected].

Using .bind and Q.nfcall at call sites is very ugly anyway, so you can create a method that does all this:

mongoose.Model.prototype.saveForResult = function() {
    return Q.nbind(this.save, this)().spread(function(result, numberAffected) {
        return result;
    });
};

Then:

Q.spread([
    employee.saveForResult(),
    dept.saveForResult()
],function(emp,dept){
    console.log(JSON.stringify(emp));
    console.log(JSON.stringify(dept));
    mongoose.disconnect();
})
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top