https://kotlinlang.org logo
#coroutines
Title
# coroutines
m

Muhammad Usman

04/17/2021, 12:57 PM
Hi how can result be returned from this extension function
Copy code
open class RootResponse<T>  {
    var success: Boolean = false
    var msg: String? = null
    var data: T? = null
}
fun <E, T : RootResponse<E>> CoroutineScope.launchCatching(blk: suspend () -> T): Result<E> {
    this.launch {
        kotlin.runCatching { blk() }
            .onSuccess {
                if (it.success && it.data != null) {
                    Result.success(it.data)
                } else {
                    Result.failure<String>(Throwable(it.msg))
                }
            }.onFailure {
                Result.failure<String>(it)
            }
    }

}
d

Dominaezzz

04/17/2021, 1:16 PM
What do you want
launchCatching
to do exactly? You've broken quite a few conventions here, so I'm not sure.
r

rkeazor

04/18/2021, 3:01 PM
you probably shouldn't return Result. I think there is a warning against that
d

Dominaezzz

04/18/2021, 3:02 PM
The warning was recently lifted I think
r

rkeazor

04/18/2021, 3:10 PM
really didn't know that ,I guess that api must be complete. . You can probably just use suspendCancellableCoroutine, and wrap the run catching block in cont.resume
m

Muhammad Usman

04/19/2021, 3:44 AM
Hi i want to reduce the boilerplate when calling rest apis(retrofit) by using fun 'callApiNew' instead of 'callApiOld' can anyone please confirm is it possible?
Copy code
@FormUrlEncoded
    @POST("mobile/auth/login")
    suspend fun login(
        @Field("username") email: String,
        @Field("password") password: String,
    ): RootResponse<UserModel>

    fun callApiOld() {
        lifecycleScope.launch {
            kotlin.runCatching {
                WebService.getInstance().login("email", "pass")
                //suspendable retrofit api call
            }.onSuccess {
                if (it.success && it.data != null) {
                    //handle succes
                } else {
                    it.msg //handle error
                }
            }.onFailure {
                //handle error
            }
        }

    }

    fun callApiNew() {
        lifecycleScope.launchCatching {
            WebService.getInstance().login("email", "pass")
        }.onSuccess { userModel->
            //use user model here mean actual response from api
        }.onFailure {
            //handle error
        }
    }
u

uli

04/19/2021, 4:36 PM
well, the issue is, that you can not return a result until the result is created.
if you are on a thread that you can block, use the blocking apis of retrofit. if you can not block, use coroutines all the way. i,e. make
CoroutineScope.launchCatching
a suspend fun and remove the
launch
10 Views