I have a suspend function userRepo.updateUserWithNewPersonalDetails(details)
and after executing this function I want to execute success()
function which is a call back.
but the issue is success()
is not getting executed.
any suggestions on how to get this to work.
this sequence does not work
SUCCESS -> {
progress.postValue(GONE)
userRepo.updateUserWithNewPersonalDetails(details) // EXECUTED
success() // NOT EXECUTED
}
if I change it to call success() first then save to repo, it works fine. but this is not the right way of doing it I think.
could you suggest please
SUCCESS -> {
progress.postValue(GONE)
success() // EXECUTED
userRepo.updateUserWithNewPersonalDetails(details) // EXECUTED
}
Fragment call
viewModel.save(personalDetails) { activity?.onBackPressed() }
ViewModel
fun save(details: PersonalDetails, success: () -> Unit) {
viewModelScope.launch {
userRepo.savePersonalDetails(details).collect {
when (it.status) {
LOADING -> {
progress.postValue(VISIBLE)
}
SUCCESS -> {
progress.postValue(GONE)
userRepo.updateUserWithNewPersonalDetails(details)
success() // THIS IS NOT EXECUTED
}
ERROR -> {
progress.postValue(GONE)
error.postValue(ErrorResult(errorCode = SNACKBAR_ID_USER_DETAILS_SAVE_FAIL))
}
}
}
}
}
userRepository
suspend fun updateUserWithNewPersonalDetails(details: PersonalDetails) {
userDao.get().collect { cachedUser ->
val updatedCachedUser = UserDB(cachedUser.id, etc..)
userDao.save(updatedCachedUser)
}
}
CodePudding user response:
can you please show me the function that you call?, did you already use the breakpoint to make sure the function it self was called?. cause if you dont, i think you might use nullable variable and the value will retrieved after the suspend function (userRepo.blabla()) finished, if yes. maybe you can call .invokeOnCompletion { /your Success Function/ success() }
CodePudding user response:
success()
method isn't called because you collect Flow
in updateUserWithNewPersonalDetails
method:
userDao.get().collect {...}
It suspends a coroutine execution. My guess is that it is a Hot Flow (infinite), which doesn't complete until coroutine is completed. That's why userDao.get().collect
suspends execution.
I don't quite understand what you are trying to achieve in the updateUserWithNewPersonalDetails
method, but it seems it doesn't update the DB. If you want to update user details in the DB, you don't need to collect Flow
. You should have something like this:
suspend fun updateUserWithNewPersonalDetails(details: PersonalDetails) {
userDao.update(details)
}
where userDao.update(details)
is a suspend
method, which updates DB:
suspend fun update(details: PersonalDetails)