Filtering an array using a function that returns a promise
Things get interesting when you want to filter an array of values, with a function returning promise of boolean instead of just a boolean.
Prerequisite:
- Basic understanding on how the promises work.
- Basic knowledge of Typescript.
It is easy to filter an array of values using a function returning a boolean. Let see an example.
In the above code, we use a function called isEven
to filter an array of numbers and return only the even numbers. We know that, the isEven
function takes a number
and returns a boolean
value representing, whether the number is even or not.
Lets change the isEven
function to return Promise<boolean>
instead of just a boolean
and try to filter values.
As you can see, we got all the values in the output, which is wrong. Now, why did that happen?
This happened because the filter got a Promise
as a result of executing the isEvenPromise
function and not a boolean
. As per the javascript's truthy concept, an object is always true
, hence all the values are returned as output.
Now we know what the problem is, but how to solve this? Lets write a function to solve this.
First, lets define the type of our function to get a clear idea of how the function is going to look like.
- First parameter is the array of
values
of typeT
that has to be filtered. - Second parameter is a function that accepts a value of type
T
as an input and returns aPromise
, of typeboolean
. - Return type is a
Promise
, holding an array of typeT
.
One thing to be noted is that, the return type of this function is not T[]
but Promise<T[]>
. This is because, the filter function does not return a boolean
but returns a Promise<boolean>
. We cannot remove the value out of a Promise
. The only we to use the value returned from a Promise
is either by using a then
or by using async
and await
.
Now lets write the body of the function.
One important thing to note here is that,
filter
function in JS passes theindex
of the array as a second argument to the accepted function.
In Line 1
, we map
the values array to the fn
instead of filtering it directly, so that we can obtain the boolean
values first. In Line 2
, we convert the array of promises into a promise, holding an array of booleans. We use the await
keyword here to access the booleans
. In Line 3
, we filter the values
using the i
th element in the booleans
array which holds the boolean value of i
th element.
A representation of what each variable will hold as a result of the execution of each line is shown below.
For input values [1, 2, 3, 4, 5, 6]
,
Line 1:
Line 2:
Line 3:
As you can see, the result at Line 3
is properly filtered even numbers from the input array.
The entire code is shown below.
If you are a fan of one liner like me, then the filterPromise
function can be written in a single line like below.
Hope you enjoyed! Happy Hacking!