0

I have configLiveData:LiveData<Response<ConfigFile>> where Response is

sealed class Response<out T> {
  data class Success<out T>(val data: T) : Response<T>()
  data class Failure<out T>(val message: String) : Response<T>()
}

now in ViewModel I want to transform configLiveData to two different LiveDatas 1.LiveData<ConfigFile> and 2. LiveData<String> and as a result of transformation one of them will be empty. but I want to get ride of LiveData<Response<ConfigFile>> and have instead of it LiveData<ConfigFile>

 override suspend fun fetchConfigFile(): Response<ConfigFile> {
    return suspendCoroutine { cont ->
      EnigmaRiverContext.getHttpHandler().doHttp(AppConstants.getPath().append("config/appConfig.json").toURL(),
          JsonHttpCall("GET"), object : JsonReaderResponseHandler() {
        override fun onSuccess(jsonReader: JsonReader) {
          try {
            val successObject = ApiConfigFile(jsonReader)
            cont.resume(Response.Success(successObject.toPresenterModel()))
          } catch (e: IOException) {
            cont.resume(Response.Failure(e.message))
          } catch (e: Exception) {
            cont.resume(Response.Failure(e.message ))
          }
        }

        override fun onError(error: Error?) {
          cont.resume(Response.Failure("error.message"))
        }
      })
    }
  }

It is how my Repository looks like 

  private fun fetchConfig() {
    uiScope.launch {
      when (val result = homeRepository.fetchConfigFile()) {
        is Response.Success<ConfigFile> -> {
          postValue(Response.Success(result.data))
        }
        is Response.Failure -> postValue(Response.Failure(result.message))
      }
    }
  }


class ConfigFileLiveData @Inject constructor(val homeRepository: IHomeRepository) : LiveData<Response<ConfigFile>>() {
  private val liveDataJob = Job()
  private val uiScope = CoroutineScope(Dispatchers.Main + liveDataJob)

  override fun onActive() {
    fetchConfig()
  }

  private fun fetchConfig() {
    viewModelScope.launch {
      when (val result = homeRepository.fetchConfigFile()) {
        is Response.Success<ConfigFile> -> {
          postValue(Response.Success(result.data))
        }
        is Response.Failure -> postValue(Response.Failure(result.message))
      }
    }
  }
}

I have `ConfigFileLiveData` which is singleton and I want to use this liveData in other viewModels as I need to fetch config once and use it in different ViewModels


class ConfigFileLiveData @Inject constructor(val homeRepository: IHomeRepository) : LiveData<Response<ConfigFile>>() {

  override fun onActive() {
    fetchConfig()
  }

  private fun fetchConfig() {
    viewModelScope.launch {
      when (val result = homeRepository.fetchConfigFile()) {
        is Response.Success<ConfigFile> -> {
          postValue(Response.Success(result.data))
        }
        is Response.Failure -> postValue(Response.Failure(result.message))
      }
    }
  }
}

I.S
  • 1,904
  • 2
  • 25
  • 48

1 Answers1

0

In Viewmodel Define two LiveData variable.

private var configLiveData = MutableLiveData<ConfigFile>()
private var stringLiveData = MutableLiveData<String>()

Modify this method

  private fun fetchConfig() {
        uiScope.launch {
          when (val result = homeRepository.fetchConfigFile()) {
            is Response.Success<ConfigFile> -> {
              configLiveData.value = Response.Success(result.data)
            }
            is Response.Failure -> {
              stringLiveData.value = Response.Failure(result.message)
             }
          }
        }
      }
Rajnish suryavanshi
  • 3,168
  • 2
  • 17
  • 23
  • I have updated my post yes I agree it is a solution but in your solution you are directly using repository method while I want to use ConfigFileLiveData (which I have updated) as ConfigFileLiveData is singleton and I donot need to fetch it evverywhere – I.S Jul 23 '19 at 08:51