Reputation: 666
I am having trouble with a function returning an Array of undefined
.
Here is code:
classMethods.getQueries = function(models, dbId, dateStart, dateEnd) {
return new Promise(function(resolve, reject) {
// Fetch database.
.then(extractQueries, reject)
.then(sortQueries, reject)
.then(onlyTen, reject)
.then(addText, reject)
.then(function(queries) {
console.log("getQueries finished", queries); // Array of 10× undefined!
resolve(queries);
}, reject);
// Functions here.
});
};
Everything is fine until the addText
function:
function addText(queries) {
return Promise.all(queries.map(function(query) {
models.queries.findById(query.queryId, {
raw: true,
attributes: [ "query" ]
})
.then(function(queryFetched) {
query.text = queryFetched.query;
console.log(query);
return Promise.resolve(query);
}, function(error) {
return Promise.reject(error);
});
}));
};
This is giving me an output like:
"getQueries finished" [ undefined ×10 ]
10×
[query database]
{ queryId: "…", text: "…" }
I have no idea why the promise is returned while the loop is not finished.
Upvotes: 17
Views: 21708
Reputation: 13672
Promise.all
accepts an Array of Promise
objects.
You’re getting an Array of undefined
because you’re not returning any Promise in your map
callback:
function addText(queries) {
return Promise.all(queries.map(function(query) {
// Add `return` here or the `map` returns an Array of `undefined`.
return models.queries
.findById(query.queryId, {
raw: true,
attributes: [ "query" ]
})
.then(function(queryFetched) {
query.text = queryFetched.query;
console.log(query);
return Promise.resolve(query);
}, function(error) {
return Promise.reject(error);
});
}));
};
A primitive value such as undefined
will resolve immediately in Promise.all
, therefore it resolves before any of the Promises in your callback resolve.
Upvotes: 38
Reputation: 156
I was having the same problem, my Promise.all(list)
, results in an array of undefined, I used the same approach of adding a return
to my function.
Upvotes: 0
Reputation: 666
So here the solution of my problem:
function addText(queries) {
return Promise.all(queries.map(function(query) {
return new Promise(function(resolve, reject) {
models.queries.findById(query.queryId, { raw: true, attributes: ['query'] })
.then(function(queryFetched) {
query.text = queryFetched.query;
resolve(query);
}, reject);
});
}));
};
Upvotes: 1