Search code examples
androidkotlinrx-java2android-room

How to solve error : " Not sure how to handle insert method's return type" in implement room with RX java


This is my error after that i run the sample project that i developed with Room and RX java occur :

e: /home/milad/workspace/android/WalletMVVM/app/build/tmp/kapt3/stubs/debug/com/example/walletmvvm/data/dao/CurrencyDao.java:15: error: Not sure how to handle insert method's return type.
    public abstract io.reactivex.Single<com.example.walletmvvm.data.model.CurrencyModel> insert(@org.jetbrains.annotations.NotNull()

I searched a lot but i did not find anything.

I could implement Retrofit with RX java and use it and i could run the Room Query in other thread with RX java but i could not set observer and subscribe a observable with RX java yet.

Everything sounds good

This is my Dao :

@Dao
interface CurrencyDao {

        @Query("SELECT * FROM ${DbConstants.TABLE_CURRENCY} ORDER BY ${DbConstants.NAME_CURRENCY_MODEL} ASC")
        fun getCurrencyList(): Observable<List<CurrencyModel>>

        @Insert(onConflict = OnConflictStrategy.REPLACE)
        fun insert(currencyModel: CurrencyModel): Single<CurrencyModel>
    }

This is my repository :

companion object {

    // For Singleton instantiation
    @Volatile
    private var instance: CurrencyRepository? = null

    fun getInstance(currencyDao: CurrencyDao) =
        instance ?: synchronized(this) {
            instance ?: CurrencyRepository(currencyDao).also { instance = it }
        }
}

fun getCurrencyList(): Observable<List<CurrencyModel>>? {

    return currencyDao.getCurrencyList()
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())

}

This is my fragment that me observer the data :

private fun initObservers() {
    val getCurrencyListObserver = currencyViewModel.getCurrencyLists()
    getCurrencyListObserver?.subscribeWith(getCurrenciesFromDatabase())
}

private fun getCurrenciesFromDatabase() : Observer<List<CurrencyModel>> {


    return object : Observer<List<CurrencyModel>> {
        override fun onComplete() {

        }

        override fun onSubscribe(d: Disposable) {

        }

        override fun onNext(t: List<CurrencyModel>) {

            t.let {

                showResult(it.size.toString() + " items")
                setRecyclerData(it)
                binding.listSize = it.size
            }
        }

        override fun onError(e: Throwable) {

        }
    }
}

For implement this i study this in medium and study this

I see sample code about Kotlin in googlesamples/android-architecture-components but they dont use observer


Update :

because after that i remove single i cant use :

currencyDao.insert(currency)
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe()

And currencyDao.insert(currency) cant access to .subscribeOn() and other


Update :

i solved it when i changed the return type to Long type but i faced to new error

 @Insert(onConflict = OnConflictStrategy.REPLACE)
    fun insert(currencyModel: CurrencyModel): Single<Long>

And new error is :

e: /home/milad/workspace/android/WalletMVVM/app/build/tmp/kapt3/stubs/debug/com/example/walletmvvm/data/dao/CurrencyDao.java:11: error: Not sure how to convert a Cursor to this method's return type (java.lang.Object).
    public abstract io.reactivex.Observable<java.lang.Object> getCurrencyList();

Update :

I changed the insert return type to Completable and it fixed


Solution

  • Your:

        @Insert(onConflict = OnConflictStrategy.REPLACE)
        fun insert(currencyModel: CurrencyModel): Single<CurrencyModel>
    

    Should return a Completable not a Single

            @Insert(onConflict = OnConflictStrategy.REPLACE)
            fun insert(currencyModel: CurrencyModel): Completable
    

    That's because there is no need to return anything when your operation is done. It just enters the onComplete block on the background.