filteredBy<R> method

ValueStream<Iterable<X>> filteredBy<R>(
  1. ValueStream<R> other,
  2. bool filter(
    1. X item,
    2. R? other
    )
)

Filters this stream using a result of another stream. This allows us to apply the filter when either the filtering source changes or the original list changes.

Implementation

ValueStream<Iterable<X>> filteredBy<R>(ValueStream<R> other, bool filter(X item, R? other)) {
  final FutureOr<Iterable<X>?> first = get();
  final FutureOr<R?> otherFirst = other.get();

  /// When combining, we need to ensure at least one emission.
  final withOtherFirst = Future.value(otherFirst).asStream().whereType<R>().followedBy(other.after);
  final afterTransform = after.combineLatest(withOtherFirst, (items, R filters) {
    return items.where((item) => filter(item, filters));
  });

  if (first is Future || otherFirst is Future) {
    final firstFuture = Future.value(first).then((_first) {
      return Future.value(otherFirst).then((_otherFirst) {
        return _first?.where((item) => filter(item, _otherFirst));
      });
    });
    final afterCombined = firstFuture.asStream().expectNotNull().followedBy(afterTransform);
    return ValueStream.of(firstFuture, afterCombined);
  } else {
    final _first = first as Iterable<X>;
    final _otherFirst = otherFirst;
    return HStream(_first.where((item) => filter(item, _otherFirst!)), afterTransform);
  }
}