Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to extract string from Mono<String> in reactor core

I have a Mono<String> object in reactor. How can I get a string value from this object?

I know I can do something like below : For Mono<String> userName, I can do,

userName.map(System.out::println). 

But this will directly print the value. I want to store this string value into another variable so that I can pass that variable around to some other functions. How can I extract this value?

like image 557
Rohan Gujarathi Avatar asked Aug 05 '19 07:08

Rohan Gujarathi


People also ask

How do you get string out of mono?

Blocking way to get String from Mono<String> You can use the block() method to block the current thread indefinitely and wait for Mono to complete. If the Mono completes, then this method either returns the original value or null (Mono is empty). In case of any errors, then the exception is rethrown.

How do I extract data from mono?

Extract data from Mono in Java – blocking way This way of extracting data is discouraged since we should always use the Reactive Streams in an async and non-blocking way. We can use the block() method that subscribes to a Mono and block indefinitely until the next signal is received. Output: Data from Mono: Hello!

How do I get a list from Mono list?

Using block() is actually the only way to get the object from a Mono when it is emitted.

How do you find the object of a mono object?

You can retrieve the result from Mono in a non-blocking way by subscribing a Consumer that will consume all the sequences. The Consumer code block executes asynchronously only after Mono completes.


1 Answers

To answer the question directly in its simplest form - you use Mono.block().

But you almost certainly shouldn't, as this blocks the thread, defeating the point of using reactor in the first place. You should, instead, call subscribe() and then provide a consumer. The consumer will be called asynchronously when the Mono emits a value, with that value as a parameter.

There's nothing inherently stopping you just assigning the value to a field of course:

mono.subscribe(v -> this.value = v);

...but this has very limited usefulness in practice, since you won't know when that field will be initialised.

The more normal way is to either call the other methods in your subscriber all in one go:

mono.subscribe(v -> {
    oneMethodThatNeedsTheValue(v);
    anotherMethodThatNeedsTheValue(v);
});

...or to use Mono.cache() and pass it around:

class Test {

    void useMonoVal(Mono<String> mono) {
        mono.subscribe(s -> System.out.println("I need to see " + s));
    }

    void anotherMethod(Mono<String> mono) {
        mono.subscribe(s -> System.out.println("I need to talk to " + s));
    }

    public static void main(String[] args) {
        Mono myMono = Mono.just("Bob").cache();
        Test t = new Test();
        t.useMonoVal(myMono);
        t.anotherMethod(myMono);
    }

}

(The cache() method ensures that the Mono is only evluated once and then cached for all future subscribers, which is irrelevant when using the just() factory of course, but just there for the sake of a complete example.)

To expand, the whole point of using a reactive paradigm (and therefore reactor, and by extension its Mono and Flux objects) is that it enables you to code in a non-blocking way, meaning that the current thread of execution isn't "held up" waiting for the mono to emit a value.

Side note: I'm not sure it's directly relevant to the question, but you can't do a.map(System.out::println); - you probably mean a.subscribe(System.out::println);.

like image 173
Michael Berry Avatar answered Sep 23 '22 14:09

Michael Berry