Friday, December 1, 2023

Reactive Programming - Convert List[Mono[T]] to Mono[List[T]]

Hello world,

It's been a while, but I'm finally get back into a new groove with programming. My hope for the new year (2024) is to write more on my lessons transitioning to reactive programming.

First, what is different between Reactive Programming vs Functional Programming?

I think this author's article does a splendid job in explaining the difference.

Also, what is different between Reactive Programming vs Imperative Programming?

This article is decent but I think JavaScript is the true language to consider the need for reactive programming due to the ability to process data without order (non-sequentially).

Okay, for now, let's dive into a challenge I had this morning (and I'll need to back track throughout next year). My issue this morning dealt with my need to:

Convert a List<Mono<T>> to a Mono<List<T>

Because, my response to the client needs to be in a Mono<T>; not List<T>.

Since I couldn't figure this out on my on with Mono.map(), Mono.flatMap() and Flux.fromIterable(), I used ChatGPT. You can see my exact question and ChatGPT's solution at the bottom of my conversation here.


Solution (from ChatGPT)

---

To convert a `List<Mono<T>>` to a `Mono<List<T>>` in a reactive programming context using Project Reactor in Java, you can use the `Flux.concat` operator along with `collectList`. Here's an example:


import reactor.core.publisher.Flux;

import reactor.core.publisher.Mono;


import java.util.List;


public class MonoListConversion {


    public static void main(String[] args) {

        // Your original List<Mono<T>>

        List<Mono<String>> monoList = getOriginalMonoList();


        // Convert List<Mono<T>> into Mono<List<T>>

        Mono<List<String>> resultListMono = Flux.concat(monoList).collectList();


        // Now, you have Mono<List<T>> as the result

        resultListMono.subscribe(System.out::println);

    }


    private static List<Mono<String>> getOriginalMonoList() {

        // Your logic to obtain List<Mono<T>>

        // For demonstration purposes, let's create a simple example

        Mono<String> mono1 = Mono.just("Value 1");

        Mono<String> mono2 = Mono.just("Value 2");

        return List.of(mono1, mono2);

    }

}


In this example, `Flux.concat` is used to concatenate the values emitted by the `Mono` instances into a single `Flux`. Then, `collectList` is used to collect the values emitted by the `Flux` into a `Mono<List>>`.

This approach ensures that the values emitted by the `Mono` instances are processed sequentially, maintaining the order of the original list. If the order is not important, you can also use `Flux.merge` instead of `Flux.concat` for concurrent processing.

---