Home > Software engineering >  how to implement ApolloGraphQl with Jetpack Compose
how to implement ApolloGraphQl with Jetpack Compose

Time:12-05

I have an app that has bottom Navigation bar which implemented with compose navigation. This bottom navigation bar navigate between different screen (each screen is a composable function).

I want to execute an enquiry using ApolloGraphQl Client inside home screen. However, if I want to execute the enquiry:

fun HomeScreen() {
    Text(text = "Home")
    val response = apolloClient.query(LaunchListQuery()).execute()
    Log.d("LaunchList", "Success ${response.data}")
    }

I get this error

Suspend function 'execute' should be called only from a coroutine or another suspend function

in ApollographQl tutorial, they used Fragments which has its own lifecycle, but I want to use composable functions and searching online didn't give me a clear answer.

I tried @oliverbj answer as:

@Preview
@Composable
fun HomeScreen() {
    val coroutineScope = rememberCoroutineScope()
    val getLaunchOnClick: () -> Unit = {
        coroutineScope.launch {
            val response = async(Dispatchers.IO) {
                apolloClient.query(LaunchListQuery()).execute()
            }
            Log.d("LaunchList", "Success ${response.await().data}")
        }
    }
    Text(text = "Home")
    Button(onClick = getLaunchOnClick) {
        Text("Launch")
    }
}

and it worked thanks @oliverbj also thanks for @heyheyhey

CodePudding user response:

To fix the error you are getting, you can use the withContext function to execute your Apollo GraphQL query within a coroutine. Here's how you can do that:

@Composable
fun HomeScreen() {
    val coroutineScope = rememberCoroutineScope()
    val getLaunchOnClick: () -> Unit = {
        coroutineScope.launch {
            val response = withContext(Dispatchers.IO) {
                apolloClient.query(LaunchListQuery()).execute()
            }
            Log.d("LaunchList", "Success ${response.data}")
        }
    }
    Text(text = "Home")
}

The withContext function lets you specify which coroutine dispatcher to use, in this case Dispatchers.IO, which is the recommended dispatcher for performing blocking IO operations such as making network requests.

You can also use the async function to simplify the code even further:

@Composable
fun HomeScreen() {
    val coroutineScope = rememberCoroutineScope()
    val getLaunchOnClick: () -> Unit = {
        coroutineScope.launch {
            val response = async(Dispatchers.IO) {
                apolloClient.query(LaunchListQuery()).execute()
            }
            Log.d("LaunchList", "Success ${response.await().data}")
        }
    }
    Text(text = "Home")
}

The async function returns a Deferred object, which you can await to get the result of the suspended computation.

  • Related