Search code examples
androidrx-javaandroid-roomrx-android

Chain a RxJava observable to udpate/create an entry in Room database


I want a way to search and update an existing entry in Room with RxJava. If there's no record it should create a new one.

For example, lets say I have the following queries:

@Insert
Single<Long> createContent(Content content);

@Query("SELECT * FROM Content WHERE contentId = :contentId")
Single<Content> searchContent(String contentId);

My Goals:

  1. Check if there's a previous data and return its value
  2. If there's no record create a new one and return it's value

Problem with this approach:

  1. Whenever there's no record the from @Query, the Single<Content> directly goes to error ignoring any map/flatMap operator
  2. The @Insert query returns a Single<Long> but the @Query returns a Single<Content>

Is there any way to call and return a new Observable from the error? Something like this:

daoAccess.searchContent(contentId)
                .subscribeOn(Schedulers.io())
                .map(Resource::success)
                .onErrorResumeNext(new Function<Throwable, Single<Content>>() {
                    @Override
                    public Single<Content> apply(Throwable throwable) throws Exception {
                        return daoAccess.createContent(contentId);
                    }
                })

Solution

  • You could use Single.onErrorResumeNext():

    daoAccess.searchContent(contentId)
             .subscribeOn(Schedulers.io())
             .map(Resource::success)
             .onErrorResumeNext(throwable ->
                 daoAccess.createContent(content)
                          .map(id -> Resource.success(content))
             )