lastWhere method

Future<T> lastWhere(
  1. bool test(
    1. T element
    ), {
  2. T orElse()?,
})

Finds the last element in this stream matching test.

Returns a future that is completed with the last element of this stream for which test returns true.

If no such element is found before this stream is done, and an orElse function is provided, the result of calling orElse becomes the value of the future. If orElse throws, the returned future is completed with that error.

If this stream emits an error at any point, the returned future is completed with that error, and the subscription is canceled.

A non-error result cannot be provided before this stream is done.

Similar too firstWhere, except that the last matching element is found instead of the first.

Example:

var result = await Stream.fromIterable([1, 3, 4, 7, 12, 24, 32])
    .lastWhere((element) => element % 6 == 0, orElse: () => -1);
print(result); // 24

result = await Stream.fromIterable([1, 3, 4, 7, 12, 24, 32])
    .lastWhere((element) => element % 10 == 0, orElse: () => -1);
print(result); // -1

Implementation

Future<T> lastWhere(bool test(T element), {T orElse()?}) {
  _Future<T> future = new _Future();
  late T result;
  bool foundResult = false;
  StreamSubscription<T> subscription =
      this.listen(null, onError: future._completeError, onDone: () {
    if (foundResult) {
      future._complete(result);
      return;
    }
    if (orElse != null) {
      _runUserCode(orElse, future._complete, future._completeError);
      return;
    }
    try {
      throw IterableElementError.noElement();
    } catch (e, s) {
      _completeWithErrorCallback(future, e, s);
    }
  }, cancelOnError: true);

  subscription.onData((T value) {
    _runUserCode(() => test(value), (bool isMatch) {
      if (isMatch) {
        foundResult = true;
        result = value;
      }
    }, _cancelAndErrorClosure(subscription, future));
  });
  return future;
}