RxJava flatMapIterable with a Single - Springboot

Viewed 158

I'm using Single to retrieve a list from database and since it is only supposed to return a single value I think is the option to go.

I'm having problems retrieving a single value Long from that list that I want to store in a variable.

Single<List<Currency>> currencyListOrigin = 
    currencyService.getCurrencyByCodeLike(request.getMonedaOrigen());

This is what I want to achieve, but changing this code to get the same result but with Single

Long codOriginCurrency = currencyListOrigin
                             .stream()
                             .findFirst()
                             .map(Currency::getId)
                             .orElse(null);
2 Answers

Using Single<Long> is not a valid option here. You should use a Maybe as the return type can be empty (there is no null when we talk about reactive streams).

If you want to get the id of Currency as a Maybe<Long> type you should proceed with the following code:

private Maybe<Long> getCurrencyId() {
    return getCurrencyByCodeLike()
            .flatMapMaybe(currency -> currency.stream()
                    .findFirst()
                    .map(Currency::getId)
                    .map(Maybe::just)
                    .orElseGet(Maybe::empty)
            );
}
  private Maybe<Long> getCurrencyId() {
    return currencyService
            .getCurrencyByCodeLike(request.getMonedaOrigen())
            .filter(new Predicate<List<String>>() {  
                @Override
                public boolean test(List<String> currencies) throws Exception {
                    return !currencies.isEmpty(); // Make sure the list has at least one element.
                }
            }) 
            .map(new Function<List<String>, Long>() {
                @Override
                public Long apply(List<String> currencies) throws Exception {
                    return currencies.get(0).getId(); // Get the first element and return the id.
                }
            }) 
            .switchIfEmpty(Maybe.<Long>empty()); // If the list is empty, return Maybe.empty().
}

From what I understand, you want to return the currency id of the first element in the list of currencies, then the above code should do the job.

Also note that RxJava2 onwards you cannot emit null in the stream. Instead we can use Maybe and emit Maybe.empty() when the list is empty.

Related