Make sure batch create calls back with correct data

See https://github.com/strongloop/loopback/issues/1031
This commit is contained in:
Raymond Feng 2015-01-29 11:52:39 -08:00
parent ce39f8ab01
commit 7d42202d40
2 changed files with 53 additions and 31 deletions

View File

@ -160,39 +160,38 @@ DataAccessObject.create = function (data, callback) {
} }
if (Array.isArray(data)) { if (Array.isArray(data)) {
var instances = []; // Undefined item will be skipped by async.map() which internally uses
var errors = Array(data.length); // Array.prototype.map(). The following loop makes sure all items are
var gotError = false; // iterated
var wait = data.length; for (var i = 0, n = data.length; i < n; i++) {
if (wait === 0) { if (data[i] === undefined) {
callback(null, []); data[i] = {};
} }
for (var i = 0; i < data.length; i += 1) {
(function (d, i) {
Model = self.lookupModel(d); // data-specific
instances.push(Model.create(d, function (err, inst) {
if (err) {
errors[i] = err;
gotError = true;
} }
modelCreated(); async.map(data, function(item, done) {
})); self.create(item, function(err, result) {
})(data[i], i); // Collect all errors and results
} done(null, {err: err, result: result || item});
return instances;
function modelCreated() {
if (--wait === 0) {
callback(gotError ? errors : null, instances);
if(!gotError) {
instances.forEach(function(inst) {
inst.constructor.emit('changed');
}); });
}, function(err, results) {
if (err) {
return callback && callback(err, results);
} }
// Convert the results into two arrays
var errors = null;
var data = [];
for (var i = 0, n = results.length; i < n; i++) {
if (results[i].err) {
if (!errors) {
errors = [];
} }
errors[i] = results[i].err;
} }
data[i] = results[i].result;
}
callback && callback(errors, data);
});
return data;
} }
var enforced = {}; var enforced = {};

View File

@ -153,6 +153,29 @@ describe('manipulation', function () {
}).should.be.instanceOf(Array); }).should.be.instanceOf(Array);
}).should.have.lengthOf(3); }).should.have.lengthOf(3);
}); });
it('should create batch of objects with beforeCreate', function(done) {
Person.beforeCreate = function(next, data) {
if (data && data.name === 'A') {
return next(null, {id: 'a', name: 'A'});
} else {
return next();
}
};
var batch = [
{name: 'A'},
{name: 'B'},
undefined
];
Person.create(batch, function(e, ps) {
should.not.exist(e);
should.exist(ps);
ps.should.be.instanceOf(Array);
ps.should.have.lengthOf(batch.length);
ps[0].should.be.eql({id: 'a', name: 'A'});
done();
});
});
}); });
describe('save', function () { describe('save', function () {