Robert Tomas G IV Robert Tomas G IV - 5 months ago 24
Javascript Question

Filtering undefined promises with BlueBird + React Native

I am attempting to fetch multiple rss feeds, get each of their promises, and use bluebird to merge the arrays of each returned promises to get an array of relevant content for the user.

However, on occasion some rss feeds are down or don't have images, and those promises returned an undefined where an array should be as shown below:

enter image description here

So I am looking for a way to filter out these bad promises and keep the good ones. I am very new to bluebird and promises in general, and would appreciate any help. Here's my code now (that doesn't filter out any promises at all, but does merge their arrays):

//combining promises
var that = this;
return Promise.all(rss_feeds)
.then((res) => {
for (var q = 0; q < res.length; q++)
{
for (var a =0; a < res[q].length; a++)
{
final_array.push(res[q][a]);
}
}
//console.log('The following array of objects was constructed and is now being shuffled');
//console.log(final_array.length);
that.shuffle(final_array);
//console.log(final_array);
return final_array;
});

Answer

Once a value is wrapped in a Promise, the only way of inspecting it is to use the .then method. As a matter of fact, the reason why promises are so powerful is that .then allows manipulating the wrapped value without caring of its actual existence. In other words, promises represent the computational context of an eventual value.

As a consequence, you first need to move from an array of promises to a promise of an array with Promise#all and then reason on the array of eventual values (some of which might be undefined). After that, you can filter and return a new promise comprising only the desired values.

This leads to:

// dummy values to simulate the use case
var arrayOfPromises = [Promise.resolve(1), Promise.resolve(undefined), Promise.resolve(2)]

var result = Promise.all(arrayOfPromises).then(ps => ps.filter(p => p));
result.then(console.log.bind(console));  // output: [1, 2]

Note that Bluebird provides an additional Promise#filter method as a shorthand. However, the above code has the advantage of working with bluebird and native ES6 promises alike.