Method call after returning Mono<Void>
Asked Answered
L

3

24

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>?

Legislator answered 25/7, 2018 at 9:20 Comment(2)
Is notificationLogReactiveRepository blocking?Transaction
no, it's store NotificationLog obj in DB and return Mono<NotificationLog>Legislator
T
25

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());
}
Transaction answered 25/7, 2018 at 14:43 Comment(0)
R
30

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();
Rodenticide answered 25/7, 2018 at 13:56 Comment(0)
T
25

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());
}
Transaction answered 25/7, 2018 at 14:43 Comment(0)
D
11

Try it this way:

Mono.empty().then() 
Drollery answered 7/4, 2020 at 11:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.