0

I am working with API and Room to get list of Service Technician.

I want to do the following:

  1. Query to getAll() from the Service Technician database table.
  2. Display results to users instantly.
  3. If it is empty or fails to get database results, make API call to get the same list.
  4. Make an API call to get updated list of Service Technician.
  5. Save them into a database table.
  6. Refresh UI changes based on the latest database content.

Here is what I have, and it works. But I think that it can be improved:

  • This looks like not needed call, if I could use somehow Flowable .flatMap(ids -> techniciansDbRepository.getServiceTechnicians())
  • I can not use Flowable since filter(ServiceTechnician::isActive).toList(); never completes and I do not get result in subscribe().
  public void getServiceTechnicians() {
    disposables = RxUtil.initDisposables(disposables);

    Disposable disposable = techniciansDbRepository.getServiceTechnicians()
      .subscribeOn(Schedulers.io())
      .onErrorResumeNext(throwable -> techniciansApiRepository.getServiceTechnicians())
      .flatMap(serviceTechnicians -> techniciansApiRepository.getServiceTechnicians())
      .flatMap(techniciansDbRepository::insertAll)
      .flatMap(ids -> techniciansDbRepository.getServiceTechnicians())
      .observeOn(AndroidSchedulers.mainThread())
      .subscribe(
        serviceTechnicians -> view.onServiceTechniciansLoaded(serviceTechnicians),
        view::handleError
      );

    disposables.add(disposable);
  }
public class ServiceTechniciansDbRepository implements ServiceTechniciansRepository {

  private final ServiceTechnicianDao dao;

  public ServiceTechniciansDbRepository(ServiceTechnicianDao dao) {
    this.dao = dao;
  }

  @Override public Single<List<ServiceTechnician>> getServiceTechnicians() {
    return dao.getAll()
      .flatMapPublisher(Flowable::fromIterable)
      .map(serviceTechnicianAndUser -> ServiceTechnicianMapper.convertToApiModel(
        serviceTechnicianAndUser.getServiceTechnician(),
        serviceTechnicianAndUser
      ))
      .filter(ServiceTechnician::isActive)
      .toList();
  }
}
@Dao public abstract class ServiceTechnicianDao implements BaseDao<ServiceTechnicianDb> {

  @Transaction
  @Query("SELECT * FROM service_technician")
  public  abstract Single<List<ServiceTechnicianAndUser>> getAll();

  @Insert(onConflict = OnConflictStrategy.REPLACE)
  public abstract void insertUser(UserDb user);

}
public interface BaseDao<E> {

  @Insert(onConflict = OnConflictStrategy.REPLACE)
  Single<Long> insert(E e);

  @Insert(onConflict = OnConflictStrategy.REPLACE)
  Single<List<Long>> insert(List<E> list);

  @Update Single<Integer> update(E e);

  @Delete Single<Integer> delete(E e);

}
public class ServiceTechniciansApiRepository implements ServiceTechniciansRepository {

  private final ServiceTechnicianApi api;

  public ServiceTechniciansApiRepository(ServiceTechnicianApi api) {
    this.api = api;
  }

  @Override public Single<List<ServiceTechnician>> getServiceTechnicians() {
    return api.getServiceTechnicians()
      .subscribeOn(Schedulers.io());
  }

  @Override public Single<List<Long>> insertAll(List<ServiceTechnician> serviceTechnicians) {
    return Single.error(new CanNotBeUsedWithApiException());
  }
}

Any idea of how I could improve more this code?

Zookey
  • 2,637
  • 13
  • 46
  • 80
  • I think this post could help you: https://stackoverflow.com/questions/40797144/andorid-rxjava-how-to-get-data-from-cache-and-and-the-same-time-update-it-in-th – Juanjo Berenguer May 05 '20 at 14:45
  • Is there a way without a merge operator? Since I want instantly to show results from database and then in background call for API and save again into the database and then again refresh UI since it happened change in the database. – Zookey May 05 '20 at 15:00
  • Hi @Zookey, I think you could combine both but take first the result from database. Here is another post: https://stackoverflow.com/questions/37569906/how-to-handle-multiple-data-sources-with-rxjava – Juanjo Berenguer May 06 '20 at 14:21

0 Answers0