Processing Optional Value from Mono in Project Reactor
Asked Answered
M

3

19

I want to have a Mono that calls another async method that returns an Optional type to:

  1. have a value if the Optional is not empty,
  2. is MonoEmpty if the Optional value is empty.

Here's what I do right now:

Mono.fromCallable(() -> someApi.asyncCall()) .filter(Optional::isPresent) .map(Optional::get)

Obviously, this is not ideal since it uses two operators after the callable completed. If possible, I'd like to have the Mono.empty() or mono value from inside fromCallable.

What is the best way to achieve what I want?

Magda answered 7/11, 2018 at 8:46 Comment(0)
E
30

There is an alternative with flatMap that's a bit better than Optional.isPresent and Optional.get that can lead to accidentally calling get on empty Optional:

Mono.fromCallable(() -> someApi.asyncCall())
  .flatMap(optional -> optional.map(Mono::just).orElseGet(Mono::empty))
Eutrophic answered 7/11, 2018 at 11:21 Comment(1)
How about Mono.fromCallable(() -> someApi.asyncCall()).flatMap(Mono::justOrEmpty)Agriculturist
M
14

Mono have justOrEmpty method that you can use with Optional<? extends T> type. When Optional.empty() == true we would have MonoEmpty.

Create a new Mono that emits the specified item if Optional.isPresent() otherwise only emits onComplete.

Mono<String> value = Mono.justOrEmpty(someApi.asyncCall());
Mcgray answered 6/11, 2020 at 15:33 Comment(2)
The problem here is you make the call someApi.asyncCall() immediately. accepted answer is better solution.Federalize
I checked the source!! someApi.asyncCall() is invoked immediately. not lazy. The expectation is - mono should not execute anything unless someone subscribesFederalize
Y
5

How about:

Optional<Integer> optional = Optional.of(5);
Mono<Optional<Integer>> monoWithOptional = Mono.just(optional);
Mono<Integer> monoWithoutOptional = monoWithOptional.flatMap(Mono::justOrEmpty);
Yaelyager answered 23/8, 2019 at 19:24 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.