Hi how can result be returned from this extension ...
# coroutines
m
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
What do you want
launchCatching
to do exactly? You've broken quite a few conventions here, so I'm not sure.
r
you probably shouldn't return Result. I think there is a warning against that
d
The warning was recently lifted I think
r
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
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
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