user1578872
user1578872

Reputation: 9108

Reactive programming - Return response when the result is empty

I have a reactive code below which does the following.

  1. query items table by ID - (itemRepository.findByd(itemId))
  2. Create a map from the result from Step1
  3. Invoke retrieveItemsQty from DB

Here, it works fine when the Step1 returns one or more result and retrieveItemsQty method fails when the result is empty. My requirement is to return back when the first step result(itemRepository.findByd) is empty. Not sure how to do this?

private Mono<Long> updateItemsQty(final Long itemId) {
        return itemRepository.findByd(itemId).collectList()
                .zipWhen((items) -> Mono.just(items.stream()
                        .collect(Collectors.toMap(ItemQty::getId, ItemQty::getQty))))
                .map((tuple) -> tuple.getT2())
                .zipWhen((items) -> qtyRepository
                        .retrieveItemsQty(items.keySet()).collectList())
                .zipWhen((tuple) -> reduceItemQty(tuple.getT2(), tuple.getT1(), itemId))
                .flatMap((response) -> {
                    return Mono.just(itemId);
                });
    }

I tried switchIfEmpty and defaultIfEmpty like the below.

return itemRepository.findByd(itemId).collectList()
                    .switchIfEmpty(). /// Looks like the return statement is not allowed here.
                    .zipWhen((items) -> Mono.just(items.stream()
                            .collect(Collectors.toMap(ItemQty::getId, ItemQty::getQty))))

Upvotes: 0

Views: 3195

Answers (1)

Alex
Alex

Reputation: 5982

In case you want to keep the current flow, the easiest way would be to use filter

return itemRepository.findByd(itemId)
   .collectList()
   .filter(items -> !items.isEmpty())
   ...

but I would suggest to simplify the flow to make it more readable and don't overuse reactive operators where you don't really need them. For example, something like

return itemRepository.findByd(itemId)
    .collectList()
    .flatMap(items -> {
        if (items.isEmpty()) {
            return Mono.empty();
        }

        Map<Long, Integer> itemMap = items.stream()
                .collect(Collectors.toMap(ItemQty::getId, ItemQty::getQty));

        return retrieveItemsQty(itemMap.keySet())
                .collectList()
                .flatMap(availableQty -> reduceItemQty(availableQty, itemMap, itemId));
    })
    .then(Mono.just(itemId));

you could simplify even futher and move inner body into a separate method

Upvotes: 1

Related Questions