Docs
Launch GraphOS Studio

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 , variables are prefixed with the dollar sign.

Also add the cursor and hasMore to the , 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 in Sandbox Explorer by using the pane under the main body of the Variables. If you omit the $cursor , 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 will be re-executed every time the cursor changes.

Also keep a reference to response so we can access the hasMore and cursor 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 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 .

Test scrolling

Click Run. You can now see all SpaceX 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
Edit on GitHubEditForumsDiscord

© 2024 Apollo Graph Inc.

Privacy Policy

Company