Question: I am reading about Kotlin coroutine in Google 's documentation. I'm adviced to use withContext(Dispacher.IO) to a different thread to main-safety. But I have a problem , fetchData() done before response from server so fetchData() return null result. Any help that I appreciate.

<https://developer.android.com/kotlin/coroutines/coroutines-best-practices#main-safe>

```
class GameRemoteDataSource @Inject constructor(val api : GameApi) {
    val IODispatcher: CoroutineDispatcher = Dispatchers.IO

    suspend fun fetchData() : Resource<ListGameResponse> {
        var resource : Resource<ListGameResponse> = Resource.loading(null)
        withContext(IODispatcher){
            Log.d("AAA Thread 1", "${Thread.currentThread().name}")
            api.getAllGame(page = 1).enqueue(object : Callback<ListGameResponse>{
                override fun onResponse(
                    call: Call<ListGameResponse>,
                    response: Response<ListGameResponse>
                ) {
                    if(response.code()==200){
                        resource = Resource.success(response.body())
                    }else{
                        resource = Resource.success(response.body())
                    }
                    Log.d("AAA code",response.code().toString())
                }
                override fun onFailure(call: Call<ListGameResponse>, t: Throwable) {
                    resource = Resource.error(t.message.toString(),null)
                    Log.d("AAA Thread", "${Thread.currentThread()}")
                }

            })
            Log.d("AAA Thread", "${Thread.currentThread()}")
            Log.d("AAA resource",resource.data.toString()+ resource.status.toString())
        }
        return resource
    }
}

```

Answer: 
`withContext` is not helpful for converting an asynchronous function with callback into suspending code that can be used in a coroutine. It is more applicable to converting *synchronous* blocking code. Your non-working strategy of creating an empty variable and trying to fill it in the callback to synchronously return is described in the answers to [this question](https://stackoverflow.com/questions/57330766/why-does-my-function-that-calls-an-api-return-an-empty-or-null-value).

For an asynchronous function with callback, if it returns a single value like your code above, this is typically converted to a suspend function using `suspendCoroutine` or `suspendCancellableCoroutine`. If it returns a series of values over time (calls the callback multiple times), it would be fitting to use `callbackFlow` to convert it to a Flow that can be collected in a coroutine.

But it looks like you're using Retrofit, which already has a suspend function alternatives to `enqueue` so you don't need to worry about all this. You can use the `await()` or `awaitResponse()` functions instead. In this case, `await()` would return `ListGameResponse` and `awaitResponse()` would return `Response<ListGameResponse>`. So `awaitResponse()` is better if you need to check the response code.

Awaiting returns the response and throws an exception if there's an error, so you can use try/catch instead of adding a failure listener.

```
class GameRemoteDataSource @Inject constructor(val api : GameApi) {

    suspend fun fetchData(): Resource<ListGameResponse> {
        return try {
            val response = api.getAllGame(page = 1).awaitResponse()
            Log.d("AAA code", response.code().toString())
            Resource.success(response.body())
        } catch (exception: Exception) {
            Resource.error(exception.message.toString(),null)
        }
    }

}

```
You should use `suspendCancellableCoroutine` to convert asynchronous API into a coroutine flow, like this

```kotlin
suspend fun fetchData(): ListGameResponse = withTimeout(Duration.seconds(60)) {
  suspendCancellableCoroutine<ListGameResponse> { cont ->
    api.getAllGame(page = 1).enqueue(object : Callback<ListGameResponse> {
      override fun onResponse(
          call: Call<ListGameResponse>,
          response: Response<ListGameResponse>
      ) {
        Log.d("AAA code", response.code().toString())
        cont.resume(response.body())
      }

      override fun onFailure(call: Call<ListGameResponse>, t: Throwable) {
        cont.resumeWithException(t)
      }
    })
  }
}

```