3

I'm using mvvm architecture in my app ,this is my code :

class ProductRepository : BaseRepository() {

   private val mutableLiveData = MutableLiveData<ProductsModel>()

   fun getProducts(catId: String): MutableLiveData<ProductsModel> {
        if (internetAvailable) {
            scope.launch {
                val request = api.getProducts(catId)
                withContext(Dispatchers.Main) {
                    try {
                        val response = request.await()
                        mutableLiveData.value = response


                    } catch (e: HttpException) {
                        // Log exception //
                        Log.v("this", e.message);

                    } catch (e: Throwable) {
                        // Log error //)
                        Log.v("this", e.message);
                    }
                }
            }
        }
        return mutableLiveData
    }
}

the repository returns a MutableLiveData by the value of ProductsModel .this is my viewModel class :

class ProductsViewModel :ViewModel(){
    val repository=ProductRepository()

    private val _products=MutableLiveData<ProductsModel>()
    val products:LiveData<ProductsModel>
        get()=_products

    fun getProducts(catId:String){
        _products.value=repository.getProducts(catId)
    }
}

this is the error: enter image description here

I don't understand this error, how can I fix it ? why is it telling me that the type is not true?

Community
  • 1
  • 1
Navid Abutorab
  • 1,667
  • 7
  • 31
  • 58
  • 2
    `_products` is a `MutableLiveData`. Hence `_products.value` is a `ProductModel` property. If `getProducts()` on your repository returned a `ProductModel`, then `_products.value=repository.getProducts(catId)` would work. However, that is not what `getProducts()` returns. – CommonsWare Oct 14 '19 at 14:47
  • @CommonsWare thanks for reply but as you can see in my repository , it returns a value of MutableLiveData not just ProductModel – Navid Abutorab Oct 14 '19 at 14:55
  • 1
    Correct. I do not know why your repository is doing what it is doing. Personally, I would have the repository have a `suspend` function to return the `ProductModel`, with all of the `LiveData` stuff inside of the viewmodel. – CommonsWare Oct 14 '19 at 15:00
  • @CommonsWare , if I understand you , you mean I just return the ProductModel from the repository and use it as LiveData in my viewmodel ? – Navid Abutorab Oct 14 '19 at 15:27
  • 1
    [This sample project](https://gitlab.com/commonsguy/cw-jetpack-kotlin/tree/v0.5/DiceLight/src/main/java/com/commonsware/jetpack/diceware) shows a repository exposing a `suspend` API with a viewmodel making it available to the UI via `LiveData`. [Here is another sample](https://gitlab.com/commonsguy/cw-jetpack-kotlin/tree/v0.5/Bookmarker). [Here is a third](https://gitlab.com/commonsguy/cw-jetpack-kotlin/tree/v0.5/ContentEditor), and [a fourth](https://gitlab.com/commonsguy/cw-jetpack-kotlin/tree/v0.5/Weather), all from [this book](https://commonsware.com/Jetpack). – CommonsWare Oct 14 '19 at 15:31

1 Answers1

1

You have to take the value of the LiveData Example :

products.value=repository.getProducts(catId).value

But the most preferable way is to use Transformations

private val catId = MutableLiveData<String>()

 val products: LiveData<ProductsModel> = Transformations.switchMap(catId) { catId->
    if (catId == null) {
        AbsentLiveData.create<ProductsModel>()
    } else {
        repository.getProducts(catId)
    }
}
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
VasFou
  • 1,561
  • 1
  • 22
  • 39