1

I have

  • An array of objects
  • A function permission(obj): Promise<boolean>

How can I filter this array by the promise?

I've tried numerous things, and the closest I got was

of(arr).pipe(
  switchMap(items =>
    from(items)
     .pipe(
       mergeMap(item =>
         fromPromise(permission(item)).pipe(
           map(shown => ({show, item})),
           filter(data => data.shown),
           map(data => data.item)
         )
       ))
     ));

But that just seems needlessly complicated.

I had hoped I could do it more simple like of(arr).pipe(filterByPromise(permission)), but can't seem to figure out how.

I made a Stackblitz https://stackblitz.com/edit/rxjs-g1u8yk

StackBlitz code

import { of } from 'rxjs'; 
import { map, filter } from 'rxjs/operators';

// Mocked 3rd party function
function visible(obj): Promise<boolean> {
  return new Promise(resolve => {
    const shouldShow = obj.shouldShow < 30;
    resolve(shouldShow);
  });
}

const arr = [{
  shouldShow: 39,
  data1: 'abc',
  data2: 'bcd'
}, {
  shouldShow: 22,
  data1: 'cde',
  data2: 'def'
}];

of(arr).pipe(
  filter(obj => visible(obj))
).subscribe(result => console.log(result));
Daniel
  • 10,641
  • 12
  • 47
  • 85
  • 2
    Your code can be reduced to `from(arr).pipe( mergeMap(element => from(visible(element)).pipe(filter(show => show), map(() => element))) )` – JB Nizet Aug 03 '19 at 08:04

1 Answers1

1

JB Nizet suggested nice solution, but it would be better to use concatMap, if item order matters. Here the difference between concatMap and mergeMap is explained.

from(arr).pipe(
  concatMap(element => from(visible(element)).pipe(
    filter(show => show),
    map(() => element)
  ))
).subscribe(console.log);

The other way is to transform and zip the array, like this. But the solution about is more elegant I think.

zip(...arr.map(obj => from(visible(obj)))).pipe(
  map(visible => arr.filter((item, i) => visible[i]))
).subscribe(console.log);

Here is working example of both solutions.

Valeriy Katkov
  • 33,616
  • 20
  • 100
  • 123