Releases: apollographql/apollo-client
v4.0.0-alpha.10
Major Changes
-
#12559
49ace0e
Thanks @jerelmiller! -ObservableQuery.variables
can now be reset back to empty when callingreobserve
withvariables: undefined
. Previously thevariables
key would be ignored sovariables
would remain unchanged. -
#12559
49ace0e
Thanks @jerelmiller! -never
is no longer supported as a validTVariables
generic argument for APIs that requirevariables
as part of its type. UseRecord<string, never>
instead. -
#12559
49ace0e
Thanks @jerelmiller! - When passing avariables
key with the valueundefined
, the value will be replaced by the default value in the query, if it is provided, rather than leave it asundefined
.// given this query const query = gql` query PaginatedQuery($limit: Int! = 10, $offset: Int) { list(limit: $limit, offset: $offset) { id } } `; const observable = client.query({ query, variables: { limit: 5, offset: 0 }, }); console.log(observable.variables); // => { limit: 5, offset: 0 } observable.reobserve({ variables: { limit: undefined, offset: 10 } }); // limit is now `10`. This would previously be `undefined` console.log(observable.variables); // => { limit: 10, offset: 10 }
-
#12562
90bf0e6
Thanks @jerelmiller! -client.query
no longer supports afetchPolicy
ofstandby
.standby
does not fetch and did not returndata
.standby
is meant for watched queries where fetching should be on hold.
Minor Changes
-
#12557
51d26ae
Thanks @jerelmiller! - Add ability to specify message formatter forCombinedGraphQLErrors
andCombinedProtocolErrors
. To provide your own message formatter, override the staticformatMessage
property on these classes.CombinedGraphQLErrors.formatMessage = ( errors, { result, defaultFormatMessage } ) => { return "Some formatted message"; }; CombinedProtocolErrors.formatMessage = (errors, { defaultFormatMessage }) => { return "Some formatted message"; };
-
#12546
5dffbbe
Thanks @jerelmiller! - Add a staticis
method to error types defined by Apollo Client.is
makes it simpler to determine whether an error is a specific type, which can be helpful in cases where you'd like to narrow the error type in order to use specific properties from that error.This change applies to the following error types:
CombinedGraphQLErrors
CombinedProtocolErrors
ServerError
ServerParseError
UnconventionalError
Example
import { CombinedGraphQLErrors } from "@apollo/client"; if (CombinedGraphQLErrors.is(error)) { console.log(error.message); error.errors.forEach((graphQLError) => console.log(graphQLError.message)); }
-
#12561
99d72bf
Thanks @jerelmiller! - Add the ability to detect if an error was an error was emitted from the link chain. This is useful if your application throws custom errors in other areas of the application and you'd like to differentiate them from errors emitted by the link chain itself.To detect if an error was emitted from the link chain, use
LinkError.is
.import { LinkError } from "@apollo/client"; client.query({ query }).catch((error) => { if (LinkError.is(error)) { // This error originated from the link chain } });
Patch Changes
-
#12559
49ace0e
Thanks @jerelmiller! - Thevariables
option used with various APIs are now enforced more consistently across the client whenTVariables
contains required variables. If requiredvariables
are not provided, TypeScript will now complain that it requires avariables
option.This change affects the following APIs:
client.query
client.mutate
client.subscribe
client.watchQuery
useBackgroundQuery
useQuery
useSubscription
useSuspenseQuery
-
#12559
49ace0e
Thanks @jerelmiller! - Fix type ofvariables
returned fromuseLazyQuery
. Whencalled
isfalse
,variables
is nowPartial<TVariables>
instead ofTVariables
. -
#12562
90bf0e6
Thanks @jerelmiller! -client.query
no longer supportsnotifyOnNetworkStatusChange
in options. An error will be thrown if this option is set. The effects of this option were not observable byclient.query
sinceclient.query
emits a single result. -
#12557
51d26ae
Thanks @jerelmiller! - Update format of the error message forCombinedGraphQLErrors
andCombinedProtocolErrors
to be more like v3.x.console.log(error.message); - `The GraphQL server returned with errors: - - Email not found - - Username already in use` + `Email not found + Username already in use`
-
#12559
49ace0e
Thanks @jerelmiller! -ObservableQuery.variables
has been updated to returnTVariables
rather thanTVariables | undefined
. This is more consistent with the runtime value where an empty object ({}
) will be returned when thevariables
option is not provided.
v3.13.8
v4.0.0-alpha.9
Major Changes
-
#12536
e14205a
Thanks @jerelmiller! - An initial loading state is now emitted fromObservableQuery
when subscribing ifnotifyOnNetworkStatusChange
is set totrue
. -
#12512
e809b71
Thanks @jerelmiller! -notifyOnNetworkStatusChange
now defaults totrue
. This means that loading states will be emitted (core API) or rendered (React) by default when callingrefetch
,fetchMore
, etc. To maintain the old behavior, setnotifyOnNetworkStatusChange
tofalse
indefaultOptions
.new ApolloClient({ defaultOptions: { watchQuery: { // Use the v3 default notifyOnNetworkStatusChange: false, }, }, });
Patch Changes
-
#12536
e14205a
Thanks @jerelmiller! - The returnednetworkStatus
inuseLazyQuery
is now set tosetVariables
when calling theuseLazyQuery
execute
function for the first time with variables. -
#12536
e14205a
Thanks @jerelmiller! - EnsureObservableQuery
stops polling if switching to astandby
fetchPolicy
. When switching back to a non-standby
fetchPolicy
, polling will resume. -
#12536
e14205a
Thanks @jerelmiller! - Ensure a loading state is emitted when calling theexecute
function after changing clients inuseLazyQuery
. -
#12542
afb4fce
Thanks @jerelmiller! - EnsureuseLazyQuery
does not return apartial
property which is not specified by the result type.
v4.0.0-alpha.8
Major Changes
-
#12539
dd0d6d6
Thanks @jerelmiller! -onError
link now uses a singleerror
property to report the error that caused the link callback to be called. This will be an instance ofCombinedGraphQLErrors
in the event GraphQL errors were emitted from the terminating link,CombinedProtocolErrors
if the terminating link emitted protocol errors, or the unwrapped error type if any other non-GraphQL error was thrown or emitted.- const errorLink = onError(({ graphQLErrors, networkError, protocolErrors }) => { - graphQLErrors.forEach(error => console.log(error.message)); + const errorLink = onError(({ error }) => { + if (error.name === 'CombinedGraphQLErrors') { + error.errors.forEach(rawError => console.log(rawError.message)); + } });
-
#12533
73221d8
Thanks @jerelmiller! - Remove theonError
andsetOnError
methods fromApolloLink
.onError
was only used byMockLink
to rewrite errors ifsetOnError
was used. -
#12531
7784b46
Thanks @jerelmiller! - Mocked responses passed toMockLink
now accept a callback for therequest.variables
option. This is used to determine if the mock should be matched for a set of request variables. With this change, thevariableMatcher
option has been removed in favor of passing a callback tovariables
. Update by moving the callback function fromvariableMatcher
torequest.variables
.new MockLink([ { request: { query, + variables: (requestVariables) => true }, - variableMatcher: (requestVariables) => true } ]);
-
#12526
391af1d
Thanks @phryneas! - The@apollo/client
and@apollo/client/core
entry points are now equal.
In the next major, the@apollo/client/core
entry point will be removed.
Please change imports over from@apollo/client/core
to@apollo/client
. -
#12525
8785186
Thanks @jerelmiller! - Throw an error when a client-only query is used in a mocked response passed toMockLink
. -
#12532
ae0dcad
Thanks @jerelmiller! - Default thedelay
for all mocked responses passed toMockLink
usingrealisticDelay
. This ensures your test handles loading states by default and is not reliant on a specific timing.If you would like to restore the old behavior, use a global default delay of
0
.MockLink.defaultOptions = { delay: 0, };
-
#12530
2973e2a
Thanks @jerelmiller! - RemovenewData
option for mocked responses passed toMockLink
or themocks
option onMockedProvider
. This option was undocumented and was nearly identical to using theresult
option as a callback.To replicate the old behavior of
newData
, useresult
as a callback and add themaxUsageCount
option with a value set toNumber.POSITIVE_INFINITY
.with
MockLink
new MockLink([ { request: { query, variables }, - newData: (variables) => ({ data: { greeting: "Hello " + variables.greeting } }), + result: (variables) => ({ data: { greeting: "Hello " + variables.greeting } }), + maxUsageCount: Number.POSITIVE_INFINITY, } ])
with
MockedProvider
<MockedProvider mocks={[ { request: { query, variables }, - newData: (variables) => ({ data: { greeting: "Hello " + variables.greeting } }), + result: (variables) => ({ data: { greeting: "Hello " + variables.greeting } }), + maxUsageCount: Number.POSITIVE_INFINITY, } ]} />
Minor Changes
-
#12532
ae0dcad
Thanks @jerelmiller! - Allow mocked responses passed toMockLink
to accept a callback for thedelay
option. Thedelay
callback will be given the current operation which can be used to determine what delay should be used for the mock. -
#12532
ae0dcad
Thanks @jerelmiller! - Introduce a newrealisticDelay
helper function for use with thedelay
callback for mocked responses used withMockLink
.realisticDelay
will generate a random value between 20 and 50ms to provide an experience closer to unpredictable network latency.realisticDelay
can be configured with amin
andmax
to set different thresholds if the defaults are not sufficient.import { realisticDelay } from "@apollo/client/testing"; new MockLink([ { request: { query }, result: { data: { greeting: "Hello" } }, delay: realisticDelay(), }, { request: { query }, result: { data: { greeting: "Hello" } }, delay: realisticDelay({ min: 10, max: 100 }), }, ]);
-
#12532
ae0dcad
Thanks @jerelmiller! - Add ability to specify a defaultdelay
for all mocked responses passed toMockLink
. Thisdelay
can be configured globally (all instances ofMockLink
will use the global defaults), or per-instance (all mocks in a single instance will use the defaults). Adelay
defined on a single mock will supercede all default delays. Per-instance defaults supercede global defaults.Global defaults
MockLink.defaultOptions = { // Use a default delay of 20ms for all mocks in all instances without a specified delay delay: 20, // altenatively use a callback which will be executed for each mock delay: () => getRandomNumber(), // or use the built-in `realisticDelay`. This is the default delay: realisticDelay(), };
Per-instance defaults
new MockLink( [ // Use the default delay { request: { query }, result: { data: { greeting: "Hello" } }, }, { request: { query }, result: { data: { greeting: "Hello" } }, // Override the default for this mock delay: 10, }, ], { defaultOptions: { // Use a default delay of 20ms for all mocks without a specified delay delay: 20, // altenatively use a callback which will be executed for each mock delay: () => getRandomNumber(), // or use the built-in `realisticDelay`. This is the default delay: realisticDelay(), }, } );
v3.13.7
v3.13.6
v4.0.0-alpha.7
Major Changes
-
#12513
9c3207c
Thanks @phryneas! - Removed the@apollo/client/react/context
and@apollo/client/react/hooks
entry points. Please use@apollo/client/react
instead. -
#12513
9c3207c
Thanks @phryneas! - Removed the@apollo/client/react/parser
entry point. There is no replacement.
Patch Changes
v4.0.0-alpha.6
Major Changes
-
#12485
d338303
Thanks @jerelmiller! - Throw an error for queries and mutations if the link chain completes without emitting a value. -
#12484
9a8b9ce
Thanks @jerelmiller! - Removeloading
,networkStatus
, andpartial
properties on all promise-based query APIs. These properties were mostly static and were unnecessary since promise resolution guaranteed that the query was not longer loading.This affects the following APIs:
client.query
client.refetchQueries
client.reFetchObservableQueries
client.resetStore
observableQuery.fetchMore
observableQuery.refetch
observableQuery.reobserve
observableQuery.setVariables
- The
useLazyQuery
execute
function
Minor Changes
-
#12497
ff2cbe1
Thanks @jerelmiller! - Add adata
property toCombinedGraphQLErrors
that captures any partial data returned by the GraphQL response whenerrors
are also returned. -
#12488
c98b633
Thanks @phryneas! - Add a new method for static SSR of React components,prerenderStatic
.
The old methods,getDataFromTree
,getMarkupFromTree
andrenderToStringWithData
have been deprecated in favor ofprerenderStatic
.If used with React 19 and the
prerender
orprerenderToNodeStream
apis from
react-dom/static
, this method can now be used to SSR-prerender suspense-enabled
hook APIs.
v4.0.0-alpha.5
Major Changes
-
#12478
5ea6a45
Thanks @jerelmiller! - Removevariables
from the result returned fromuseSubscription
. -
#12476
6afff60
Thanks @jerelmiller! - Subscriptions now emit aSubscribeResult
instead of aFetchResult
. As a result, theerrors
field has been removed in favor oferror
. -
#12475
3de63eb
Thanks @jerelmiller! - Unify error behavior on mutations for GraphQL errors and network errors by ensuring network errors are subject to theerrorPolicy
. Network errors created when using anerrorPolicy
ofall
will now resolve the promise and be returned on theerror
property of the result, or stripped away when theerrorPolicy
isnone
. -
#12475
3de63eb
Thanks @jerelmiller! -client.mutate
now returns aMutateResult
instead ofFetchResult
. As a result, theerrors
property has been removed in favor oferror
which is set if either a network error occured or GraphQL errors are returned from the server.useMutation
now also returns aMutateResult
instead of aFetchResult
. -
#12475
3de63eb
Thanks @jerelmiller! - Mutations no longer report errors if the GraphQL result from the server contains an empty array of errors. -
#12476
6afff60
Thanks @jerelmiller! - Unify error behavior on subscriptions for GraphQL errors and network errors by ensuring network errors are subject to theerrorPolicy
. Network errors that terminate the connection will now be emitted on theerror
property passed to thenext
callback followed by a call to thecomplete
callback. -
#12478
5ea6a45
Thanks @jerelmiller! - Remove deprecatedonSubscriptionData
andonSubscriptionComplete
callbacks fromuseSubscription
. UseonData
andonComplete
instead. -
#12476
6afff60
Thanks @jerelmiller! - GraphQL errors or network errors emitted while using anerrorPolicy
ofignore
in subscriptions will no longer emit a result if there is nodata
emitted along with the error. -
#12476
6afff60
Thanks @jerelmiller! - Subscriptions no longer emit errors in theerror
callback and instead provide errors on theerror
property on the result passed to thenext
callback. As a result, errors will no longer automatically terminate the connection allowing additional results to be emitted when the connection stays open.When an error terminates the downstream connection, a
next
event will be emitted with anerror
property followed by acomplete
event instead.
Minor Changes
- #12487
b695e5e
Thanks @phryneas! - Split out SSR-specific code from useQuery hook, remove RenderPromises
Patch Changes
-
#12487
b695e5e
Thanks @phryneas! -useQuery
withssr: false
- previously,skip
had a higher priortity thanssr: false
whilessr: false
had a higher priority thanfetchPolicy: "standby"
(which is roughly equivalent toskip
).This priority has been adjusted so now both
skip
andfetchPolicy: "standby"
have a higher priority thanssr: false
and will returnloading: false
, whilessr: false
will only come after those and will returnloading: true
if those are not set. -
#12475
3de63eb
Thanks @jerelmiller! - Fix an issue where passingonError
touseMutation
would resolve the promise returned by themutate
function instead of rejecting when using anerrorPolicy
ofnone
. -
#12475
3de63eb
Thanks @jerelmiller! - Fix an issue where additional response properties were returned on the result returned fromclient.mutate
, such as@defer
payload fields. These properties are now stripped out to correspond to the TypeScript type.
v4.0.0-alpha.4
Major Changes
-
#12463
3868df8
Thanks @jerelmiller! -ObservableQuery.setOptions
has been removed as it was an alias ofreobserve
. Prefer usingreobserve
directly instead.const observable = client.watchQuery(options); // Use reobserve to set new options and reevaluate the query - observable.setOptions(newOptions); + observable.reobserve(newOptions);
As a result of this change,
reobserve
has been marked for public use and is no longer considered an internal API. ThenewNetworkStatus
argument has been removed to facilitate this change. -
#12470
d32902f
Thanks @phryneas! -ssrMode
,ssrForceFetchDelay
anddisableNetworkFetches
have been reworked:Previously, a
ObservableQuery
created byclient.query
orclient.watchQuery
while one of those were active would permanently be changed from afetchPolicy
of"network-only"
or"cache-and-network"
to"cache-first"
, and stay that way
even long afterdisableNetworkFetches
would have been deactivated.Now, the
ObservableQuery
will keep their originalfetchPolicy
, but queries
made duringdisableNetworkFetches
will just apply thefetchPolicy
replacement
at request time, just for that one request.ApolloClient.disableNetworkFetches
has been renamed toApolloClient.prioritizeCacheValues
to better reflect this behaviour. -
#12465
a132163
Thanks @jerelmiller! - Flatten out React hook types. As a result, the base types have been removed. Prefer using the hook types instead. Removed types include:BaseMutationOptions
BaseQueryOptions
BaseSubscriptionOptions
ObservableQueryFields
MutationSharedOptions
QueryFunctionOptions
-
#12463
3868df8
Thanks @jerelmiller! -useQuery
no longer returnsreobserve
as part of its result. It was possible to usereobserve
to set new options on the underlyingObservableQuery
instance which differed from the options passed to the hook. This could result in unexpected results. Instead prefer to rerender the hook with new options.
Patch Changes
- #12465
a132163
Thanks @jerelmiller! - Rename all React hook result types and options. These types have all moved under a namespace that matches the hook name. For example,useQuery
exportsuseQuery.Options
anduseQuery.Result
types. As such, the old hook types have been deprecated and will be removed in v5.