Reputation: 1039
Inserting multiple documents with mongodb in the same request I'm getting undefined value.
.post(function (req, res) {
...
Item.create(data)
.then(function (item) {
var modelOtherItem;
OtherItem.create({
...
}).then(function (otherItem){
modelOtherItem = otherItem;
modelOtherItem; // here I get the expected value
});
res.status(201);
res.json({
item: item, // has a value
otherItem: modelOtherItem // -> is undefined
});
});
Upvotes: 2
Views: 346
Reputation: 35501
Promises return immediately but their then
callbacks execute asynchronously. That means you are accessing modelOtherItem
before it's assigned a value. The easiest fix would be to add your code inside the then
callback (you can also get rid of the modelOtherItem
variable):
post(function (req, res) {
// ...
Item.create(data)
.then(function (item) {
OtherItem.create({
// ...
}).then(function (otherItem){
// add code here
res.status(201);
res.json({
item: item, // has a value
otherItem: otherItem // also has value
});
});
});
One thing to note that you can create all of your items with one call by passing an array to Model.collection.insert(array...
or, if using Mongoose, Model.create(array...
If you models can be created independently of one another (meaning that creation of any item doesn't depend on any other item), you can use the Promise.all method that takes an array of promises and resolves once all of the promises in that array resolve as well:
post(function (req, res) {
// ...
// create an array that will hold item creation promises
let promises = [];
// add the promise that creates the item
promises.push(Item.create(...));
// add the promise that creates the other item
promises.push(OtherItem.create(...));
Promise.all(promises)
.then(function(results) { // this function is called once all promises in the array `promises` resolve
// results contains the resolved data from each promises in the array
// in the order of the promises
var item = results[0];
var otherItem = results[1];
// OR you can use ES6 `let` declaration with
// destructuring to achieve the same as above
// in a cleaner way:
// let [item, otherItem] = results;
res.status(201);
res.json({
item: item,
otherItem: otherItem
});
// in ES6, if both the object property name and the variable name are the same
// you can just specify the name once and achieve the same effect as above
// with less code:
/*
res.json({
item,
otherItem
});
*/
});
});
Upvotes: 4