Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning a null in a .map() versus .flatMap() in Reactor

Tags:

java

reactor

The following piece of code works :

// emitting employees...
.flatMap(employee -> {

    boolean isAlive = employee.isAlive();

    return Mono.just(isAlive)

            .flatMap(myBoolean -> {
                if (myBoolean) {
                    return Mono.empty();
                } 
                else {
                    return Mono.just(employee);
                }
            });

})

But I was wondering why I can't use a .map upon processing myBoolean (NullPointerException when it returns the null)

            .map(myBoolean -> {
                if (myBoolean) {
                    return null;
                } 
                else {
                    return employee;
                }
            });

I believe I lack some understanding about the map versus flatMap

In Java 8 streams I understand the difference between map and flatMap (for each item received, map emits 1, flatMap emits N)

But in Reactor I'm a bit confused. I thought that both map and flatMap emit 1 item for each element received, the difference would be that the map emits it as a Mono while flatMap doesn't. To emit N items, I would use flatMapMany.

Thanks in advance for your explanations !

like image 462
lgean Avatar asked Dec 02 '22 10:12

lgean


1 Answers

From Reactor java doc

map: Transform the item emitted by this Mono by applying a synchronous function to it.

flatMap: Transform the item emitted by this Mono asynchronously, returning the value emitted by another Mono.

In all cases, you cannot return null. It is simply forbidden by design. The main difference between map and flatMap is that the second one returns a Mono. This allows to perform an asynchronous call to something like a data base, a web service, etc.

So flatMap should be used to performed another asynchronous stuff. It's not very useful if you return a Mono.just(...). We may use flatMap to return Mono.empty() in some condition as you did. It is a frequent pattern.

Here an alternative code to emit a new object with a condition:

        .handle(myBoolean, sink -> {
            if (!myBoolean) {
                sink.next(employee);
            } // else the Mono would be empty ...
        });
like image 72
mcoolive Avatar answered Jan 03 '23 23:01

mcoolive