Search code examples
androidkotlinrx-java

Flatmap fails to cast to right one


I am trying to transform an Observable in my login function but I keep getting this error. This my code and error I am getting on flatMap

fun login(phoneNumber: String, password: String, deviceId: String) {
        // remove previous subscriptions
        disposables.clear()

        // function to save userInfo and access token
        val saveResponse = { response: LoginResponse ->
            val user = response?.user
            val token = response?.token
//            userManager.updateToken(champion, token, deviceId)
        }

        // on success callback
        val onSuccess = { isSuccess: Boolean ->
            progressBarVisibility.postValue(false)
            loginSuccess.postValue(isSuccess)
            if (!isSuccess) errorMessage.postValue("An error occurred please try again.")
        }

        // on failure callback
        val onError = { throwable: Throwable ->
            val message = when (throwable) {
                is HttpException -> when (throwable.code()) {
                    400 -> "Enter valid Phone Number or Password"
                    422 -> "Incorrect Phone Number or Password"
                    else -> throwable.toErrorMessage()
                }

                else -> "An Error Occurred."
            }

            // show error message
            errorMessage.postValue(message)
            progressBarVisibility.postValue(false)
        }

        val disposable = accountUseCase.login(LoginRequest(phoneNumber, password)).observeOnUI()
                .doOnSubscribe { progressBarVisibility.postValue(true) }
                .flatMap {
                    val resp = it.data
                    when (resp) {
                        null -> Single.just(false)
                        else -> saveResponse(it)
                    }
                }
                .subscribe(onSuccess, onError)

        // add subscription to disposables
        disposables.add(disposable)
    }

error

Type mismatch. Required: ((BaseResponse<LoginResponse>!) → SingleSource<out (???..???)>!)! Found: (BaseResponse<LoginResponse>!) → Any!

Solution

  • The problem is with the implicit return of your flatMap:

    when (resp) {
        null -> Single.just(false)
        else -> saveResponse(it)
    }
    

    In the null branch, the return type is Single<Boolean>.

    In the else branch, you return the result of saveResponse. But the return type of saveResponse is Unit, because it doesn't return anything.

    Kotlin therefore infers the return type of your flatMap to be either Single<Boolean> or Unit, and the only common supertype of these is Any.

    This is why you get the error message: Found: (BaseResponse<LoginResponse>!) → Any!

    You need to have saveResponse return something, probably also a Single<Boolean>, depending on your usecase.