0

Need to call Mono from a Mono recursively to get form full Item. I have a Pojo Item , Here I will pass the root id and try to get the item from another service. I am writing my service using sprign webflux. So I am using the webclient to call the service and returning Mono

The other service will give the Item and its immediate children. So my requirment is When I pass the ROOT id , I will get Root item and its immediate child , Root will have LM type items as child.

After getting the the Root item I need to collect all the LM ids and make again a call to the ItemService for each LM id and set them back to root item.

Here is my code to do that. Whats happening is first my RootItem is returning and then the calls to get the LM items are subscribing. I want to first get all the LM items and set them into root and respond the RootItem with new LM items.


String itemId,
String ItemName,
List<Item> items
ItemType itemType

}

Enum ItemType {

LM,ROOT,LEAF

}


getItem(itemId) {

// Returns Mono<Item> by calling anthoer service which gives me Item . Here I am using Reactive webclient to call other service.

}

getFullItem(itemId) {

    return getItem(itemId)
        .flatMap(mainItem -> {
            Predicate<Item> LM_Prdicate = p -> p.getItemType().equals(LM);
            // get the LM's from main item. at this point the LM items will not have child
            //we need to get the LM item indvidually to get its child and set back to main item.
            List<Item> LMSwihtouchild = mainItem.getItems().stream().filter(LM_Prdicate).collect(Collectors.toList()); 

            LMSwihtouchild.forEach(lmWihtoutChild -> {
                getItem(lmWihtoutChild.getId()) // here I am calling recursively to get the LM Item so that it will come with children
                .flatMap(lmWithChildren -> {
                    mainItem.getItems().removeIf(item -> item.getId().equals(lmWihtoutChild.getId())); // removing the LM item with out child from main item
                    mainItem.getContentItems().add(lmWithChildren); //Adding LM item with Children
                    return Mono.just(mainItem);
                })
                .subscribe()             
            });
            return Mono.just(mainItem); // This retruning to as  response before calling and getting the LM items with children.
        });
}

1 Answers1

0

You need to make method chain. You should not to execute .subscribe() inside .flatMap because it's not connected to your main method chain.

I've made pseudo-code by your example.

getFullItem(itemId) {
    return getItem(itemId)
        .flatMap(mainItem -> {
            Predicate<Item> LM_Prdicate = p -> p.getItemType().equals(LM);
            List<Item> LMSwihtouchild = mainItem.getItems().stream().filter(LM_Prdicate).collect(Collectors.toList()); 

            // make flux from List<Item>. It's connected to your method chain.
            return Flux.fromIterable(LMSwihtouchild)
                .flatMap(child -> getItem(child.getId())
                .collectList()
                .map(childList -> {
                    // merge result here
                    mainItem.getItems().removeIf(item -> item.getId().equals(lmWihtoutChild.getId()));
                    mainItem.getContentItems().add(lmWithChildren);
                    return mainItem;
                }      
            });
        });
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
JK.Lee
  • 261
  • 3
  • 9
  • this is working perfectly but if I am running the flux using parallel then collectList is not supported, or is there any other way I can run the flux in parallel and collect the items into list for merging. – ramesh silamala Sep 17 '20 at 08:05
  • 1
    we need to use custom collectors when using the parallel flux. Big Thanks again. – ramesh silamala Sep 17 '20 at 08:30