Join us from October 8-10 in New York City to learn the latest tips, trends, and news about GraphQL federation and API platform engineering.Join us for GraphQL Summit 2024 in NYC
Docs
Start for Free

7. Paginate results


As you might have noticed, the object returned from the LaunchListQuery is a LaunchConnection. This object has a list of , a pagination cursor, and a boolean to indicate whether more launches exist.

When using a cursor-based pagination system, it's important to remember that the cursor gives you a place where you can get all results after a certain spot, regardless of whether more items have been added in the interim.

In the previous section, you hardcoded the SMALL size directly in the , but you can also define arguments programmatically using . You will use them here to implement pagination.

Add a cursor variable, and the cursor and hasMore fields

In LaunchList.graphql, add a cursor . In GraphQL, variables are prefixed with the dollar sign.

Also add the cursor and hasMore to the query, as we will use them to paginate:

app/src/main/graphql/LaunchList.graphql
query LaunchList($cursor: String) {
launches(after: $cursor) {
cursor
launches {
id
site
mission {
name
missionPatch(size: SMALL)
}
}
hasMore
}
}

You can experiment with GraphQL variables in Sandbox Explorer by using the pane under the main body of the Variables. If you omit the $cursor variable, the server returns data starting from the beginning:

Explorer variables

Fetch the next page when reaching the end of the list

Declare and remember a cursor var, initialized to null, and make the LauchedEffect depend on it. That way, the query will be re-executed every time the cursor changes.

Also keep a reference to response so we can access the hasMore and cursor fields further down.

app/src/main/java/com/example/rocketreserver/LaunchList.kt
@Composable
fun LaunchList(onLaunchClick: (launchId: String) -> Unit) {
var cursor: String? by remember { mutableStateOf(null) }
var response: ApolloResponse<LaunchListQuery.Data>? by remember { mutableStateOf(null) }
var launchList by remember { mutableStateOf(emptyList<LaunchListQuery.Launch>()) }
LaunchedEffect(cursor) {

Pass the cursor to the LaunchListQuery, and add a special item at the end of the list which updates the cursor if hasNext is true. This will trigger a new query with the new cursor whenever the user scrolls to the end of the list, and launchList will be concatenated with the new results.

Note: this is a basic implementation of paging in Compose. In a real project you may use something more advanced, like the Jetpack Paging library.

The whole function should look like this:

app/src/main/java/com/example/rocketreserver/LaunchList.kt
@Composable
fun LaunchList(onLaunchClick: (launchId: String) -> Unit) {
var cursor: String? by remember { mutableStateOf(null) }
var response: ApolloResponse<LaunchListQuery.Data>? by remember { mutableStateOf(null) }
var launchList by remember { mutableStateOf(emptyList<LaunchListQuery.Launch>()) }
LaunchedEffect(cursor) {
response = apolloClient.query(LaunchListQuery(Optional.present(cursor))).execute()
launchList = launchList + response?.data?.launches?.launches?.filterNotNull().orEmpty()
}
LazyColumn {
items(launchList) { launch ->
LaunchItem(launch = launch, onClick = onLaunchClick)
}
item {
if (response?.data?.launches?.hasMore == true) {
LoadingItem()
cursor = response?.data?.launches?.cursor
}
}
}
}

Note that we wrap the cursor in an Optional: this is because this parameter can be omitted in the query.

Test scrolling

Click Run. You can now see all SpaceX launches back to their first FalconSat from Kwajalein Atoll!

Next, you'll add a details view that will allow you to book a seat on a .

Previous
6. Add more info to the list
Next
8. Add a details view
Rate articleRateEdit on GitHubEditForumsDiscord

© 2024 Apollo Graph Inc.

Privacy Policy

Company