# Paginating data within an expensive query

**URL:** <https://community.apollographql.com/t/paginating-data-within-an-expensive-query/7877>\
**Category:** Client SDKs\
**Tags:** client\
**Created:** [October 9, 2024, 9:15am UTC](https://community.apollographql.com/t/paginating-data-within-an-expensive-query/7877 "2024-10-09T09:15:38Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![RMHonor](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/rmhonor/32/5309_2.png) [@RMHonor](https://community.apollographql.com/u/RMHonor)\
**Post date:** [October 9, 2024, 9:15am UTC](https://community.apollographql.com/t/paginating-data-within-an-expensive-query/7877/1 "2024-10-09T09:15:38Z")

</div>

When render a page, we have several fields fetched from different backend sources, and a paginated list of data.

We want to include everything in one logical query, but when fetching more pages for the paginated section, we don’t want to fetch all the initial static fields again.

E.g.:

```auto
query myData {
  account {
    expensiveField1
    expensiveField2
    list(first: 20, cursor: "") {
      ...ListItem
    }
}

```

My first instinct was that we could create 2 separate queries, one that fires initially with all the data, and a second one which only includes the paginated field. Or alternatively could we make use of the `@include` directive any time we’re fetching after the initial request?

---

<div class="post-metadata">

**Author:** ![AnthonyMDev](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/anthonymdev/32/5972_2.png) [@AnthonyMDev](https://community.apollographql.com/u/AnthonyMDev)\
**Post date:** [October 9, 2024, 8:45pm UTC](https://community.apollographql.com/t/paginating-data-within-an-expensive-query/7877/2 "2024-10-09T20:45:43Z")

</div>

FWIW, this is exactly what we recommend in Apollo iOS. We have a pagination library that is actually set up for this use case. You provide an initial query and another query for additional pages, along with a transform function that merges the values from the pages together.

---

<div class="post-metadata">

**Author:** ![RMHonor](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/rmhonor/32/5309_2.png) [@RMHonor](https://community.apollographql.com/u/RMHonor)\
**Post date:** [October 11, 2024, 10:42am UTC](https://community.apollographql.com/t/paginating-data-within-an-expensive-query/7877/3 "2024-10-11T10:42:41Z")

</div>

Good to know, thanks. Is there a comparable helper for Apollo web?

---

<div class="post-metadata">

**Author:** ![lenz](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/lenz/32/4007_2.png) [@lenz](https://community.apollographql.com/u/lenz)\
**Post date:** [October 11, 2024, 10:52am UTC](https://community.apollographql.com/t/paginating-data-within-an-expensive-query/7877/4 "2024-10-11T10:52:48Z")

</div>

You can pass a different query into the `fetchMore` options.

---

<div class="post-metadata">

**Author:** ![michaeldouglasdev](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/michaeldouglasdev/32/4911_2.png) [@michaeldouglasdev](https://community.apollographql.com/u/michaeldouglasdev)\
**Post date:** [October 13, 2024, 3:31am UTC](https://community.apollographql.com/t/paginating-data-within-an-expensive-query/7877/5 "2024-10-13T03:31:16Z")

</div>

What is the difference between fetchMore using a different query and lazyQuery?

---

<div class="post-metadata">

**Author:** ![michaeldouglasdev](https://sea1.discourse-cdn.com/flex019/user_avatar/community.apollographql.com/michaeldouglasdev/32/4911_2.png) [@michaeldouglasdev](https://community.apollographql.com/u/michaeldouglasdev)\
**Post date:** [October 13, 2024, 12:58pm UTC](https://community.apollographql.com/t/paginating-data-within-an-expensive-query/7877/6 "2024-10-13T12:58:40Z")

</div>

I have resolved this trouble using this approach:

```auto
export const UserDetail_QueryFragment = graphql(`
  fragment UserDetail_QueryFragment on Query {
    user(id: $id) @include(if: $includeUser) {
      id
      name
      username
      createdAt
    }
  }
`);

```

```auto
const ProfileScreen_Query = graphql(`
  query ProfileScreen(
    $id: ID!
    $dataFeed: FeedPostInput!
    $includeUser: Boolean = true
  ) {
    ...UserDetail_QueryFragment
    ...ProfileDetailListPost_QueryFragment
  }
`);

```

```auto
const handleFetchMore = () => {
    const feed = useFragment(ProfileDetailListPost_QueryFragment, data);

    if (!feed?.feed.pageInfo.hasNextPage) {
      return;
    }

    fetchMore({
      variables: {
        id,
        dataFeed: {
          where: {
            authorId: {
              equals: id,
            },
          },
          connection: {
            first: 10,
            after: feed?.feed.pageInfo.endCursor,
          },
          order: {
            createdAt: OrderBy.Desc,
          },
        },
        includeUser: false,
      },
      updateQuery(prevQueryResult, { fetchMoreResult }) {
        const prevUser = useFragment(UserDetail_QueryFragment, prevQueryResult);
        const prev = useFragment(
          ProfileDetailListPost_QueryFragment,
          prevQueryResult
        );
        const moreResult = useFragment(
          ProfileDetailListPost_QueryFragment,
          fetchMoreResult
        );

        moreResult.feed.edges = [...prev.feed.edges, ...moreResult.feed.edges];

        return {
          ...prevUser,
          ...moreResult,
        };
      },
    });

```

Notice, I needed to return …prevUser because fetchMore expects the same fields structure, otherwise it will throw “Unterminated String” error.

Probably if query inside fetchMore is different that initial, you don’t need this “workaround”
