Search code examples
androidkotlinviewmodelsealed-class

Type mismatch. Required: Result<NewsResponse>! Found: Result<Response<NewsResponse>>?


I am developing android app and I have implemented success and failure cases in viemodel class but I am getting following mismatch Type mismatch. Required: Result! Found: Result<Response>

below my NewsViewModel where I have implemented success and failure cases when I am getting data

class NewsViewModel(private val repository: NewsRepository) : ViewModel() {


    private var _newsResponse= MutableLiveData<Result<NewsResponse>>()
    // Expose to the outside world
    val news: LiveData<Result<NewsResponse>> = _newsResponse
    @UiThread
    fun getNews() {
         viewModelScope.launch(Dispatchers.IO) {


             try {
                 val response = repository.getNews()
                 _newsResponse.postValue(Result.success(response))
             } catch (ioe: IOException) {
                 _newsResponse.postValue(Result.Failure("[IO] error please retry", ioe))
             } catch (he: HttpException) {
                 _newsResponse.postValue(Result.Failure("[HTTP] error please retry", he))
             }
         }
    }

         }

below my NewsRepository.ktclass

NewsRepository(
   private val apiInterface:NewsInterface
){

suspend fun getNews() = apiInterface.getNews()


}

below my Result class

sealed class Result<out T> {
    data class Success<out R>(val value: R): Result<R>()
    data class Failure(
        val message: String?,
        val throwable: Throwable?
    ): Result<Nothing>()
}

I want to know where I exactly I am making mistake what I have to do in order to fix that problem

below my news Interface

import com.example.newsworldwide.model.NewsResponse import retrofit2.Response import retrofit2.http.GET interface NewsInterface {

@GET("ApiKey")
suspend fun getNews(): Response<NewsResponse>

}


Solution

  • Your NewsInterface is returning Response<NewsResponse> & in your NewsViewModel you're passing it directly to response so it becomes Result.Success<Response<NewsResponse>> at the time of posting. That's why this error.

    Solution:

    1. Get value from body() of retrofit response class.
    2. Make it Non-nullable using(!!) as your _newsResponse live-data is accepting NewsResponse which is non-nullable. You might want to handle null case here.

    So your final code would look something like this.

    class NewsViewModel(private val repository: NewsRepository) : ViewModel() {
    
    
        private var _newsResponse= MutableLiveData<Result<NewsResponse>>()
        // Expose to the outside world
        val news: LiveData<Result<NewsResponse>> = _newsResponse
    
        @UiThread
        fun getNews() {
            viewModelScope.launch(Dispatchers.IO) {
    
                try {
                    val response = repository.getNews().body()!! //change this line
                    _newsResponse.postValue(Result.Success(response))
                } catch (ioe: IOException) {
                    _newsResponse.postValue(Result.Failure("[IO] error please retry", ioe))
                } catch (he: HttpException) {
                    _newsResponse.postValue(Result.Failure("[HTTP] error please retry", he))
                }
            }
        }
    
    }