0
votes

Consider the following sample:

I have a non completing rxjs Observable providing me with an array of numbers (e.g. of([1, 2, 3, 4, 5])) and a custom filter function that returns an Observable boolean (also non completing) for each number (signifying whether the number should be included in the result or not).

My question: What is the best combination of operators to apply this filter?

Note: A solution using toArray (like described in RxJs: Filter array with inner observable) won't work for me: The observables returned by my filter function never complete and for obvious reasons toArray can only work with streams that do.

What I came up with so far is this monster using the scan operator: https://stackblitz.com/edit/from-and-back-to-array?devtoolsheight=133&file=index.ts

I believe it works, but I can't help thinking that there must be an easier way to accomplish this. ???? Anyone have an idea?

1
Can you be more specific what are you trying to do? I don't know what's a non completing filter function returning Observable or what the stackblitz code suppsoed to do.martin
Yeah I'll try to rephrase my question a bit, but it is a complicated setting. By "non completing Observable" I mean an Observable that never calls complete() internally. (For example interval(100) creates such an Observable for testing.lentschi

1 Answers

1
votes

I think this should work.

const filtered$ = remoteSource$.pipe(
  // if new source values come in, switch to those and discard the current values
  switchMap(nums => {
    // an array of observables each emitting a number if it passes the filter or else undefined
    const checkedNumbers = nums.map(num => numFilter$(num).pipe(
      map(isValid => isValid ? num : undefined)
    ));
    // combine those observables
    return combineLatest(checkedNumbers);
  }),
  // filter out undefined values, i.e. numbers that didn't pass the filter above
  map(checkedNumers => checkedNumers.filter(num => num !== undefined)),
);

https://stackblitz.com/edit/from-and-back-to-array-6slvvf?file=index.ts