Как мне из Observable<io.rxjava> сохранить данные в List<>?

178
01 октября 2018, 10:40

Есть метод, который получает данные из json и создает Observable<>, из него мне нужно получить данные и сохранить в List<>:

@NonNull
public Observable<List<BaseProducts>> getProducts(){
    return bankApi.getProductsObservable()
            //здесь получаю result
            .map(productResponseApiResponse -> productResponseApiResponse.getResult())
            //здесь конвертирую result в готовые типы (DTO)
            .map(response -> converter.convert(response))
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread());
}

Дальше мне нужно отфильтровать данные и передать в List<>

@NonNull
private Observable<List<BaseProducts>> getActive(){
    return getProducts()
            .flatMap(Observable::fromIterable)
            .filter(products -> !products.getStatus().equals(ACTIVE_PRODUCTS))
            .toList()
            .toObservable();
}

Происходит фильтрация, как теперь мне отфильтрованный поток сохранить в List<>?

Например, если сохранить в List<>

@NonNull
public List<BaseProducts> getActiveProducts(){
    List<BaseProducts> activeProducts = new ArrayList<>();
    getProducts()
            .subscribe(products -> activeProducts.addAll(products));
    return activeProducts;
}

Но через debugger показывает, что activeProducts = null, когда products хранит в себе данные

@Inject
public ProductsItemBuilderImpl(@NonNull ProductsRepository repository) {
    this.baseProducts = repository.getActiveProducts();
}
@NonNull
@Override
public List<BaseProductsItem> build() {
    buildDeposits(baseProducts);
    buildCredits(baseProducts);
    buildDebitCards(baseProducts);
    buildCreditCards(baseProducts);
    return baseProductsItems;
}

Здесь вызываю это самый List

Answer 1

Ошибка кроется здесь:

List<BaseProducts> activeProducts = new ArrayList<>();
getProducts()
    .subscribe(products -> activeProducts.addAll(products));
return activeProducts;

Нельзя просто так взять, и вернуть значение синхронно из подписки. Точнее, делать этого совсем не стоит. RxJava создавали для реализации реактивного, асинхронного подхода.

Если более кратко — на момент выполнения строчки return activeProducts список будет ещё пуст, так как переход к ней произойдет сразу после предыдущей строчки, без ожидания выполнения переданных вами лямбд.

Слишком подробно всё расписывать не вижу смысла — про асинхронное программирование (даже в рамках Java и RxJava) исписано пол интернета, поищите статей на эту тему. На вашу ошибку я указал, обратите внимание. Вы ознакомились с операторами RxJava и начали с ней работать, но не знаете как этим пользоваться.

Не пытайтесь хранить полученные откуда-то данные у себя в полях, используйте цепочки методов. Получили данные — вызвали метод, который их сможет обработать, передали туда эти данные. Там поместили их куда-нибудь в список в адаптере, отобразили на UI, сохранили в базу и так далее. Переосмыслите подход — не храните данные в поле, а потом откуда-то вызывайте их, а сразу при получении вызывайте получателя (слушателя, подписчика), который сможет эти данные обработать.

READ ALSO
Свой десктопный редактор кода на java

Свой десктопный редактор кода на java

Хотел написать свой простенький редактор кода на java, типа консоли, но с подсказками, который подсказывает ошибки и тд

140
Как настроить activity под диагональ экрана?

Как настроить activity под диагональ экрана?

У меня есть activity мне надо, чтобы оно настраивалось под диагональ экрана пользователяЯ писал активность под диагональ экрана своего телефона

149
Почему обновляются данные во всех Map

Почему обновляются данные во всех Map

Не могу понять, каким образом у меня обновляются данные во всех трех мапах?

180
Где найти jar для support-v4

Где найти jar для support-v4

В Intellij Idea 20182 в android-проекте в коде объявлена переменная типа android

135