https://kotlinlang.org logo
#flow
Title
# flow
n

Nicolai

03/17/2022, 10:54 AM
Hi, I'm pretty new to using Flows in Kotlin so I'm having an issue I hope one of you can provide me some help to. I'm trying to chain some requests and if they fail I want them to stop the chaining and just emit an error. Preferably it would be one size fits all so I don't have to check for the Error for each response. Right now I just emit emptyFlow as the IDE will complain if I return nothing Any idea what I can do? (also any other inputs are more than welcome)
Copy code
signupUseCase.signUp(createPostRegister(email, password))
     .flatMapConcat {
         when (it) {
             is NetworkResult.Success -> loginUseCase.login(
                 createPostToken(
                     email,
                     password
                 )
             )
             is NetworkResult.Error -> {
                 it.rbError?.let { error -> handleErrors(error) }
                 emptyFlow()
             }
             else -> emptyFlow()
         }
     }
     .flatMapConcat {
         when (it) {
             is NetworkResult.Success -> {
                 prefManager.saveString(AppConstants.TOKEN_STORAGE, it.data)
                 prefManager.saveString(AppConstants.EMAIL_STORAGE, email)
                 prefManager.savePasswordEncrypted(password)
                 updateCountryUseCase.updateCountry()
                 return@flatMapConcat patchSelfUseCase.patchSelf(name, ApiConstants.fullName)
             }
             else -> emptyFlow()
         }
     }.flatMapConcat {
         when (it) {
             is NetworkResult.Success -> getSelfUseCase.getSelf()
             is NetworkResult.Error -> {
                 it.rbError?.let { error -> handleErrors(error) }
                 emptyFlow()
             }
             else -> emptyFlow()
         }
     }.flatMapConcat {
         when (it) {
             is NetworkResult.Success -> {
                 it.data?.let { self -> instance.setSelf(self) }
                 legalRevisions.value?.let { revisions ->
                     return@flatMapConcat putLegalAcceptUseCase.putLegalAccept(revisions)
                 } ?: run {
                     return@flatMapConcat emptyFlow()
                 }
             }
             is NetworkResult.Error -> {
                 it.rbError?.let { error -> handleErrors(error) }
                 emptyFlow()
             }
             else -> emptyFlow()
         }
     }.collect { signupCompleted.postValue(true) }
m

Michael Marshall

03/17/2022, 11:00 AM
What is the function signature of
signupUseCase.signUp
?
This looks more like it should be a one-shot
suspend
function than a
Flow
.
Does this make more sense?
Copy code
suspend fun NetworkResult.getResultOrNull(): Any? =
        when (this) {
            is NetworkResult.Success -> it.data
            is NetworkResult.Error -> {
                rbError?.let { error -> handleErrors(error) }
                null
            }
        }

    suspend fun foo() {
        val signUpResult = signupUseCase.signUp(createPostRegister(email, password)).getResultOrNull() ?: return

        val loginResult = loginUseCase.login(createPostToken(email, password)).getResultOrNull() ?: return

        prefManager.saveString(AppConstants.TOKEN_STORAGE, it.data)
        prefManager.saveString(AppConstants.EMAIL_STORAGE, email)
        prefManager.savePasswordEncrypted(password)
        updateCountryUseCase.updateCountry()
        val patchSelfResult = patchSelfUseCase.patchSelf(name, ApiConstants.fullName).getResultOrNull() ?: return

        val getSelfResult = getSelfUseCase.getSelf().getResultOrNull() ?: return

        instance.setSelf(getSelfResult)
        val putLegalAcceptResult = legalRevisions.value?.let { revisions -> putLegalAcceptUseCase.putLegalAccept(revisions) }
            .getResultOrNull() ?: return

        signupCompleted.postValue(true)
    }
🙌 1
n

Nicolai

03/17/2022, 11:54 AM
That does look easier and better yea... 😅
7 Views