Skip to content

Conversation

@phryneas
Copy link
Member

!docs set-base-branch main

@changeset-bot
Copy link

changeset-bot bot commented Jul 30, 2025

⚠️ No Changeset found

Latest commit: e85f1e4

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jul 30, 2025

npm i https://pkg.pr.new/apollographql/apollo-client/@apollo/client@12814

commit: e85f1e4

@github-actions
Copy link
Contributor

github-actions bot commented Jul 30, 2025

size-limit report 📦

Path Size
import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client" (CJS) 42.89 KB (0%)
import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client" (production) (CJS) 37.72 KB (0%)
import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client" 32.83 KB (0%)
import { ApolloClient, InMemoryCache, HttpLink } from "@apollo/client" (production) 27.01 KB (0%)
import { ApolloProvider } from "@apollo/client/react" 5.91 KB (0%)
import { ApolloProvider } from "@apollo/client/react" (production) 970 B (0%)
import { useQuery } from "@apollo/client/react" 7.22 KB (0%)
import { useQuery } from "@apollo/client/react" (production) 2.23 KB (0%)
import { useLazyQuery } from "@apollo/client/react" 7.1 KB (0%)
import { useLazyQuery } from "@apollo/client/react" (production) 2.14 KB (0%)
import { useMutation } from "@apollo/client/react" 6.46 KB (0%)
import { useMutation } from "@apollo/client/react" (production) 1.48 KB (0%)
import { useSubscription } from "@apollo/client/react" 6.77 KB (0%)
import { useSubscription } from "@apollo/client/react" (production) 1.79 KB (0%)
import { useSuspenseQuery } from "@apollo/client/react" 8.58 KB (0%)
import { useSuspenseQuery } from "@apollo/client/react" (production) 3.62 KB (0%)
import { useBackgroundQuery } from "@apollo/client/react" 8.32 KB (0%)
import { useBackgroundQuery } from "@apollo/client/react" (production) 3.38 KB (0%)
import { useLoadableQuery } from "@apollo/client/react" 8.28 KB (0%)
import { useLoadableQuery } from "@apollo/client/react" (production) 3.36 KB (0%)
import { useReadQuery } from "@apollo/client/react" 6.58 KB (0%)
import { useReadQuery } from "@apollo/client/react" (production) 1.63 KB (0%)
import { useFragment } from "@apollo/client/react" 6.65 KB (0%)
import { useFragment } from "@apollo/client/react" (production) 1.71 KB (0%)

@apollo-librarian
Copy link

apollo-librarian bot commented Jul 30, 2025

🛠️ Docs preview building...

The preview is currently being built.

Build ID: 55d4a3ff7b8278e012687a1b
Build Logs: View logs

@phryneas
Copy link
Member Author

!docs set-base-branch main

@phryneas
Copy link
Member Author

!docs set-base-branch main

@phryneas phryneas marked this pull request as ready for review July 30, 2025 14:14
@phryneas phryneas requested a review from a team as a code owner July 30, 2025 14:14
@phryneas phryneas requested a review from jerelmiller July 30, 2025 14:14
Copy link
Member

@jerelmiller jerelmiller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had a few comments for you. Most of it is looking good though!

});

if (loading) return "Loading...";
if (dataState === "empty") return "Loading...";
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work if the query returns an error on the first chunk since errorPolicy: 'none' sets data to undefined (so dataState will be set to empty). We probably want the conditional that checks error first before we check the dataState.

I definitely agree not using loading here makes sense since its still true while everything in streamed in. Could we update this example to instead show a small spinner to demonstrate that its still loading, but we can start rendering data? Would it make sense to use dataState for that or networkStatus === NetworkStatus.streaming?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, what about this?
Moving the next line up, but with a networkStatus error check. The error property will stay present e.g. on a refetch until data arrives, so only checking error would mask the loading/refetching state.

Suggested change
if (dataState === "empty") return "Loading...";
if (networkStatus === NetworkStatus.error) return `Error! ${error.message}`;
if (dataState === "empty") return "Loading...";

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error property will stay present e.g. on a refetch until data arrives

I'm not sure that's true. See this test:

it("if query is refetched, and an error is returned, can refetch again with successful result", async () => {
const client = new ApolloClient({
cache: new InMemoryCache(),
link: new MockLink([
{
request: { query, variables },
result: { data: dataOne },
},
{
request: { query, variables },
result: { data: dataOne, errors: [error] },
},
{
request: { query, variables },
result: { data: dataOne },
},
]),
});
const observable = client.watchQuery({ query, variables });
const stream = new ObservableStream(observable);
await expect(stream).toEmitTypedValue({
data: undefined,
dataState: "empty",
loading: true,
networkStatus: NetworkStatus.loading,
partial: true,
});
await expect(stream).toEmitTypedValue({
data: dataOne,
dataState: "complete",
loading: false,
networkStatus: NetworkStatus.ready,
partial: false,
});
await expect(observable.refetch()).rejects.toThrow(
new CombinedGraphQLErrors({ data: dataOne, errors: [error] })
);
await expect(stream).toEmitTypedValue({
data: dataOne,
dataState: "complete",
loading: true,
networkStatus: NetworkStatus.refetch,
partial: false,
});
await expect(stream).toEmitTypedValue({
data: dataOne,
dataState: "complete",
error: new CombinedGraphQLErrors({ data: dataOne, errors: [error] }),
loading: false,
networkStatus: NetworkStatus.error,
partial: false,
});
await expect(observable.refetch()).resolves.toStrictEqualTyped({
data: dataOne,
});
await expect(stream).toEmitTypedValue({
data: dataOne,
dataState: "complete",
loading: true,
networkStatus: NetworkStatus.refetch,
partial: false,
});
await expect(stream).toEmitTypedValue({
data: dataOne,
dataState: "complete",
loading: false,
networkStatus: NetworkStatus.ready,
partial: false,
});
await expect(stream).not.toEmitAnything();
});

You'll see the first emitted value after the error is the loading state without the error property set (source):

await expect(stream).toEmitTypedValue({
  data: dataOne,
  dataState: "complete",
  loading: true,
  networkStatus: NetworkStatus.refetch,
  partial: false,
});

Also verified with this useQuery test. error should only stick around if notifyOnNetworkStatusChange is false since the loading state won't be emitted to clear out the error.

I think we're safe to stick with just checking error for now. Since the rest of our docs use error pretty generally, I think it makes sense to keep this here. Maybe we kick the can down the road a bit further? It might be a good idea in general to use networkStatus more commonly anyways, but that is outside the scope of this PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough :)


<Note>

In order to use `@defer` directive, you need to choose an incremental delivery format handler . See [choosing an `incrementalHandler`](./defer#setting-up-defer-support-by-choosing-an-incrementalhandler).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In order to use `@defer` directive, you need to choose an incremental delivery format handler . See [choosing an `incrementalHandler`](./defer#setting-up-defer-support-by-choosing-an-incrementalhandler).
To use the `@defer` directive, you need to choose an incremental delivery format handler. See [choosing an `incrementalHandler`](./defer#setting-up-defer-support-by-choosing-an-incrementalhandler).

I like the AI suggestion here

phryneas and others added 4 commits August 19, 2025 14:05
Co-authored-by: Jerel Miller <jerelmiller@gmail.com>
Co-authored-by: Jerel Miller <jerelmiller@gmail.com>
Copy link
Member

@jerelmiller jerelmiller left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Had a couple minor suggestions after reading it through once more, but nothing major. I think the AI review pointed out an error so check that out as well.

@github-actions github-actions bot added the auto-cleanup 🤖 label Aug 19, 2025
@apollo-librarian
Copy link

apollo-librarian bot commented Aug 20, 2025

❌ Docs preview failed

The preview failed to build.

Build ID: 6c31692c55acb3b261f64858
Build Logs: View logs

Errors

react/api/link/apollo-link-base-batch-http

  • No item found for @apollo/client/link/batch-http!BaseBatchHttpLink.ContextOptions:interface
    react/api/link/apollo-link-base-http

  • No item found for @apollo/client/link/http!BaseHttpLink.ContextOptions:interface
    react/api/link/apollo-link-client-awareness

  • No item found for @apollo/client/link/client-awareness!ClientAwarenessLink.ContextOptions:interface
    react/api/link/apollo-link-persisted-queries

  • No item found for @apollo/client/link/persisted-queries!PersistedQueryLink.ErrorMeta:interface
    react/api/link/apollo-link

  • No item found for @apollo/client/link!ApolloLink.ExecuteContext:interface
    react/api/link/apollo-link-batch-http

  • No item found for @apollo/client/link/batch-http!BatchHttpLink.Options:interface
    react/api/link/apollo-link-context

  • No item found for @apollo/client/link/context!SetContextLink.SetContextLinkDocumentationTypes.ContextSetter:function(1)
    react/api/link/apollo-link-error

  • No item found for @apollo/client/link/error!ErrorLink.ErrorLinkDocumentationTypes.ErrorHandler:function(1)
    react/api/link/apollo-link-remove-typename

  • No item found for @apollo/client/link/remove-typename!RemoveTypenameFromVariablesLink.KeepTypenameConfig:interface
    react/api/link/apollo-link-retry

  • No item found for @apollo/client/link/retry!RetryLink.RetryLinkDocumentationTypes.AttemptsFunction:function(1)
    react/api/link/apollo-link-schema

  • No item found for @apollo/client/link/schema!SchemaLink.SchemaLinkDocumentationTypes.ResolverContextFunction:function(1)
    react/api/link/introduction

  • No item found for @apollo/client!ApolloLink.Operation:interface

@phryneas phryneas merged commit 1388659 into release-4.0 Aug 20, 2025
42 of 44 checks passed
@phryneas phryneas deleted the pr/docs-update/defer branch August 20, 2025 12:59
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 20, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants