I have 2 fragments, FragmentA contains a list of starwar characters whereas FragmentB contains details of that character. I am using viewModelScope.launch in my fragments to fetch details for a character. Below is my ViewModel
@HiltViewModel
class DetailsViewModel @Inject constructor(
private val getSpecieDetailsUseCase: GetSpecieDetailsUseCase,
private val getFilmDetailsUseCase: GetFilmDetailsUseCase,
private val getPlanetDetailsUseCase: GetPlanetDetailsUseCase,
private val mapper: CharacterDetailMapper
) : ViewModel() {
var characterDetailsModel = MutableLiveData<CharacterDetailsModel?>()
fun init(infoModel: CharacterInfoModel?) {
characterDetailsModel.postValue(null)
try {
viewModelScope.launch {
infoModel?.let {
val specieResponse = async(context = Dispatchers.IO) {
it.specieIdList?.map {
getSpecieDetailsUseCase.executeUseCase(
GetSpecieDetailsUseCase.GetSpecieDetailsRequest(
it
)
)
}
}
val filmResponse = async(context = Dispatchers.IO) {
it.filmsIdList?.map {
getFilmDetailsUseCase.executeUseCase(
GetFilmDetailsUseCase.GetFilmDetailsRequest(
it
)
)
}
}
val planetResponse = it.homeworldId?.let {
getPlanetDetailsUseCase.executeUseCase(
GetPlanetDetailsUseCase.GetPlanetDetailsRequest(
it
)
)
}
characterDetailsModel.postValue(
mapper.toModel(
name = it.name.toString(),
birth_year = it.birth_year.toString(),
height = it.height.toString(),
specieDetailsResponse = specieResponse.await(),
filmDetailsResponse = filmResponse.await(),
planetDetailsResponse = planetResponse
)
)
}
}
} catch (exception: Exception) {
exception.stackTrace
}
}
}
Above viewModelScope.launch works perfectly fine when hit for the first time but does not work for the second time [i.e going back to the previous fragment and coming back on details fragment]. The data received in the init function is also updated data however none of my async calls seem to work for the second time. onCleared method of View Model is called every time when I go to the previous fragment which I feel should clear the scope. I tried catching an exception however there is no exception thrown. I tried debugging but none of my debug points for async calls are hit.
Check how you create this viewmodel and, which is more important when. If you are using by viewModels() LAZY delegate than check when it will be initialized first time. viewModels() used this as a viewModelStoreOwner. In 99% of cases when launch doesn't work this will point to host Activity.
The solution is simple - create your own lamda which will return correct viewModelStoreOwner of Fragment or use old style of viewModel initialization.
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel = ViewModelProvider(this).get(TextClassifiedViewModel::class.java)
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With