hmble
hmble

Reputation: 140

Mono flatMap + switchIfEmpty Combo Operator?

Is there an operator that allows to process result/success whether or not Mono is empty. For example:

Mono<Bar> result = sourceMono.flatMap(n -> process(n)).switchIfEmpty(process(null));

where:

Mono<Bar> process(Foo in){
Optional<Foo> foo = Optional.ofNullable(in);
...
}

is there a shortcut operator that allows something like below or similar?

Mono<Bar> result = sourceMono.shortCut(process);

More specifically, mono.someOperator() returns Optional<Foo> which would contain null when Mono is empty and have value otherwise.

I wanted to avoid to create process method as mentioned above and just have a block of code but not sure which operator can help without duplicating block.

Upvotes: 2

Views: 2942

Answers (2)

hmble
hmble

Reputation: 140

As per above @phil's workaround, here is a reusable function:

private final <T> Mono<Optional<T>> afterSucess(Mono<T> source) {
    return source
       .map(Optional::of) //
       .defaultIfEmpty(Optional.empty());
}

then invoke in publisher line:

Foo<Bar> result = fooMono
    .transformDeferred(this::afterSucess)
    .flatMap(optionalFoo -> process(optionalFoo.orElse(null)));

Upvotes: 1

Phil Clay
Phil Clay

Reputation: 4536

There is no built-in operator to do exactly what you want.

As a workaround, you can convert the Mono<Foo> to a Mono<Optional<Foo>> that emits an empty Optional<Foo> rather than completing empty, and then operate on the emitted Optional<Foo>.

For example:

Mono<Bar> result = fooMono            // Mono<Foo>
    .map(Optional::of)                // Mono<Optional<Foo>> that can complete empty
    .defaultIfEmpty(Optional.empty()) // Mono<Optional<Foo>> that emits an empty Optional<Foo> rather than completing empty
    .flatMap(optionalFoo -> process(optionalFoo.orElse(null)));

Upvotes: 4

Related Questions