Room + RxJava2 Flowable получение пустого списка при отсутствии данных

от автора

Когда я начал использовать Room для работы с БД, я задавался вопросом, как же более правильно сформировать подписку на изменения данных в таблице БД, чтобы если при подписке не было данных, то наш репозиторий сразу возвращал пустой список, а не ждал появления данных.

Под подпиской я имею в виду получение текущих данных, а так-же отслеживание изменений в таблице БД и при изменении данных получение их в нашей подписке.

Как вы знаете, для создания подписки возвращающей новые данные при изменении данных в таблице, нужно использовать Flowable из RxJava2.

Примерно так будет выглядеть Dao интерфейс в коде:

@Dao interface DataDao {     @Query("SELECT * FROM DataTable")     fun getData(): Flowable<List<Data>> }

Но, теперь если в нашем приложении мы попытаемся получить список Data из таблицы DataTable, а в таблице нет записей, то наша Flowable подписка будет ждать появления данных в этой таблице, а нам не нужно ждать этого, нам нужно показать пользователю экран с текстом «Нет данных».

dataDao.getData()     .subscribeOn(Schedulers.io())     .observeOn(AndroidSchedulers.mainThread())     .subscribe { data ->         //если в таблице нет записей, то наша Flowable подписка будет ждать появления данных в этой таблице     }

Для получения требуемого поведения можно сделать следующе.

Добавляем в Dao функцию получения кол-ва записей в таблице:

@Query("SELECT COUNT(*) FROM DataTable") fun getDataCount(): Flowable<Int>

Данная функция сразу при вызове вернет значение 0, если в таблице нет данных, а так-же каждый раз при изменении данных в таблице будет иметь новое значение кол-ва записей.

Напишем вот такой код в нашем репозитории для получения необходимого поведения:

class DataRepository(private val dataDao: DataDao) { fun getData(): Flowable<List<Data>> {     return dataDao.getDataCount().switchMap {                   if (it > 0)                       dataDao.getData()                   else                       Flowable.just(emptyList())               }               .subscribeOn(Schedulers.io())               .observeOn(AndroidSchedulers.mainThread())     } }

В итоге мы получаем репозиторий с функцией getData() который при отсутствии данных в таблице вернет пустой список, а при появлении данных вернет новый список с данными.

Пример использования:

dataRepository.getData()     .subscribe { data ->         //репозиторий вернет либо пустой список, либо список с данными             }

p.s. В данном случае можно еще подумать над тем, что можно у функции getData в Dao поменять тип Flowable на Maybe (чтобы внутри нашей подписки не было двух Flowable ожидающих изменения данных в таблице) либо сделать dataDao.getData().take(1), но и в приведенном коде репозитория нет ничего криминального:) ведь используется switchMap.


ссылка на оригинал статьи https://habr.com/ru/articles/591819/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *