Search code examples
swiftreactive-programmingcombine

When using `last(where:)` operator, how get the emitted value?


Consider the following snippet:

enum MyError: Error {
  case test
}
let subject = PassthroughSubject<Int, MyError>()

subject
  .eraseToAnyPublisher()
  .last(where: { $0 % 2 == 0 })
  .sink(receiveCompletion: { print("Completed with: ", $0) },
        receiveValue: { print($0) })
  .store(in: &subscriptions)

subject.send(1)
subject.send(2)
subject.send(4)
subject.send(completion: .failure(MyError.test))

Output:

Completed with:  failure(...).MyError.test)

How/Which operator should to get the value 4?


Solution

  • You can catch the error, and replace the error with an Empty publisher. This creates a publisher that will complete as soon as an error is caught. You can then do last(where:) on that.

    subject
        .catch { _ in Empty() }
        .last(where: { $0 % 2 == 0 })
        .sink { print($0) }