9

I have a Flux and Mono and I'm not sure how to combine them so that I will have the mono value in each item of the Flux.

I'm trying this approach but it's not working:

Mono<String> mono1 = Mono.just("x");
Flux<String> flux1 = Flux.just("{1}", "{2}", "{3}", "{4}");

Flux.zip(mono1, flux1, (itemMono1, itemFlux1) ->  "-[" + itemFlux1 + itemMono1 + "]-").subscribe(System.out::println);

The outcome that I'm getting is -[{1}x]-

How could I combine them in order to get -[{1}x, {2}x, {3}x, {4}x]-?
Giulia Colaço
  • 93
  • 1
  • 1
  • 3

3 Answers3

15

While Kevin Hussey's solution is a correct one, I think it is better to have it another way around:

Mono<String> mono1 = Mono.just("x");
Flux<String> flux1 = Flux.just("{1}", "{2}", "{3}", "{4}");
mono1.flatMapMany(m -> flux1.map(x -> Tuples.of(x, m))).subscribe(System.out::println);

This way you have 1 subscription to mono1, instead of creating one for each value of flux1. See the marble diagram in the documentation for Flux.flatMap() method.

As suggested by Alan Sereb, I am using tuples.

Konstantin Kolinko
  • 3,854
  • 1
  • 13
  • 21
  • Could you please explain why a single subscription is preferable? – Peter Wippermann Oct 08 '20 at 14:14
  • @PeterWippermann because you can't re-subscribe to every Mono out there, e.g. Mono WebFlux won't allow you to do that twice: java.lang.IllegalStateException, if your pipeline starts with Mono doing something with input stream as well, you won't be able to re-read it twice as it will be closed. Finally, you have to be sure that your logic is resistant to repetitive calls - save entity to database without duplicates would need correct unique index and error handling/case handling ("INSERT IGNORE"). You can use mono .cache which I find a bit cheating and hacky. – Aubergine Nov 17 '20 at 18:31
  • Thanks for the explanation. I also knew about `Mono.cache()` but also think it's a code smell. – Peter Wippermann Nov 19 '20 at 10:19
6

Zip looks for pairs to add them together, your logic looks to change the values the flux.

Mono<String> mono1 = Mono.just("x");
Flux<String> flux1 = Flux.just("{1}", "{2}", "{3}", "{4}");   
flux1.flatMap(x -> mono1.map(m -> x+m)).subscribe(System.out::println);
Kevin Hussey
  • 1,582
  • 1
  • 10
  • 17
  • hi kevin could u please check this one https://stackoverflow.com/questions/71947052/what-is-mono-zipdelayerror-equal-function-in-flux – jcrshankar Apr 21 '22 at 00:14
  • if i have mono result and flux result form different service call, then how call them parallelly and merge the results – jcrshankar Apr 21 '22 at 00:15
1

In some cases, it is more complicated than concatenating strings so you have to rely on Tuples.

Flux<Object> myFlux = Flux.just(1,2,3,4);
Mono<Object> myMono = Mono.just("hello");

// combined flux with mono
myFlux.flatMap(fluxItem -> 
     myMono.map(monoItem -> Tuples.of(fluxItem, monoItem)))

// this will have pairs of ( (1, "hello"), (2, "hello"), (3, "hello"), (4, "hello") )
Alan Sereb
  • 2,358
  • 2
  • 17
  • 31