Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method call after returning Mono<Void>

I want to call the method when previous returned Mono<Void>:

 @Override
 public Mono<Void> sendEmail(EmailDto emailDto) {
 return mailReactiveClient.sendEmail(message ->
     createMessage(emailDto, emailDto.getBody(), message))
       .doOnNext(saveNotificationLog(emailDto)); //it's not work
}

  private void saveNotificationLog(EmailDto emailDto) {
    notificationLogReactiveRepository.save(NotificationLog.builder()
       ...
      .build());
  }

Method sendEmailreturns Mono<Void>.

So how to call saveNotificationLog?

UPD: Tring to make my question simplier:

 @Override
 public Mono<Void> sendEmail(EmailDto emailDto) {
 return mailReactiveClient.sendEmail(message ->
     createMessage(emailDto, emailDto.getBody(), message))
       .doOnNext(System.out.print("Hello world!"); 
}

How to call doOnNextor similar method after sendEmail return Mono<Void>?

like image 865
kostepanych Avatar asked Jul 25 '18 09:07

kostepanych


People also ask

Should you return void from a calling method?

Returning void from a calling method can, therefore, be a way of isolating the contagion, as it were. In this lies a danger, however. Imagine you have an existing synchronous method that is called in many different places of your application, and as you are modifying that method you find the need to await something asynchronously.

Why do some async methods return void?

This is in part due to the fact that async methods that return Task are "contagious", such that their calling methods' often must also become async. Returning void from a calling method can, therefore, be a way of isolating the contagion, as it were.

How to create a mono that terminates with an error immediately?

Create a Mono that terminates with an error immediately after being subscribed to. The Throwable is Expose the specified Publisher with the Mono API, and ensure it will emit 0 or 1 item. The source em A Window object is a top-level window with no borders and no menubar.

Can a method return a value when it is called?

Calling Methods that Return Values ¶ Formal parameters allow you to pass a value into a method. A method can also pass a value out when it is finished. If a method is a void method , like most of the methods we have seen so far, it does not return a value when called.


3 Answers

doOnNext, and in general all doOn* reactor methods are side-effect methods. You're not supposed to call them to do I/O work or chain operations, but rather log things and not do anything that would affect the state of the application.

In your code sample, notificationLogReactiveRepository.save returns Mono<Void>. The saveNotificationLog returns void and does not subscribe to the publisher returned by notificationLogReactiveRepository.save. This means the notification will not be saved, because nothing happens until you subscribe.

In this case, it seems you're trying to chain operations - then operators are just made for that. Your code should look like this:

@Override
public Mono<Void> sendEmail(EmailDto emailDto) {
    return mailReactiveClient.sendEmail(message ->
        createMessage(emailDto, emailDto.getBody(), message))
           .then(saveNotificationLog(emailDto));
}

private Mono<Void> saveNotificationLog(EmailDto emailDto) {
    return notificationLogReactiveRepository.save(NotificationLog.builder()
        ...
        .build());
}
like image 111
Brian Clozel Avatar answered Oct 08 '22 04:10

Brian Clozel


The Mono will not emit data, so doOnNext will not be triggered. You should use the doOnSuccess instead.

Also, your Mono need to be consumed. Without the code, we don't know if it is or not.

Some example here: I added subscribe() to consume the mono. Depending on the use of your Mono, you will have to do or not the same thing.

This print nothing:

Mono<String> m=Mono.just("test");
Mono<Void> v=m.then();
v.doOnNext(x->System.out.println("OK")).subscribe();

This print "OK":

Mono<String> m=Mono.just("test");
Mono<Void> v=m.then();
v.doOnSuccess(x->System.out.println("OK")).subscribe();
like image 23
wargre Avatar answered Oct 08 '22 04:10

wargre


Try it this way:

Mono.empty().then() 
like image 7
Michel Dambros Figueiredo Avatar answered Oct 08 '22 06:10

Michel Dambros Figueiredo