Home > Blockchain >  Non suspend function is not executed after suspend function
Non suspend function is not executed after suspend function

Time:02-11

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)
  • Related