Skip to content

Releases: apollographql/apollo-client

v4.0.0-alpha.10

17 Apr 17:51
dde5f0c
Compare
Choose a tag to compare
v4.0.0-alpha.10 Pre-release
Pre-release

Major Changes

  • #12559 49ace0e Thanks @jerelmiller! - ObservableQuery.variables can now be reset back to empty when calling reobserve with variables: undefined. Previously the variables key would be ignored so variables would remain unchanged.

  • #12559 49ace0e Thanks @jerelmiller! - never is no longer supported as a valid TVariables generic argument for APIs that require variables as part of its type. Use Record<string, never> instead.

  • #12559 49ace0e Thanks @jerelmiller! - When passing a variables key with the value undefined, the value will be replaced by the default value in the query, if it is provided, rather than leave it as undefined.

    // 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 a fetchPolicy of standby. standby does not fetch and did not return data. standby is meant for watched queries where fetching should be on hold.

Minor Changes

  • #12557 51d26ae Thanks @jerelmiller! - Add ability to specify message formatter for CombinedGraphQLErrors and CombinedProtocolErrors. To provide your own message formatter, override the static formatMessage 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 static is 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! - The variables option used with various APIs are now enforced more consistently across the client when TVariables contains required variables. If required variables are not provided, TypeScript will now complain that it requires a variables 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 of variables returned from useLazyQuery. When called is false, variables is now Partial<TVariables> instead of TVariables.

  • #12562 90bf0e6 Thanks @jerelmiller! - client.query no longer supports notifyOnNetworkStatusChange in options. An error will be thrown if this option is set. The effects of this option were not observable by client.query since client.query emits a single result.

  • #12557 51d26ae Thanks @jerelmiller! - Update format of the error message for CombinedGraphQLErrors and CombinedProtocolErrors 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 return TVariables rather than TVariables | undefined. This is more consistent with the runtime value where an empty object ({}) will be returned when the variables option is not provided.

v3.13.8

17 Apr 16:40
87d0521
Compare
Choose a tag to compare

Patch Changes

v4.0.0-alpha.9

11 Apr 20:09
90de488
Compare
Choose a tag to compare
v4.0.0-alpha.9 Pre-release
Pre-release

Major Changes

  • #12536 e14205a Thanks @jerelmiller! - An initial loading state is now emitted from ObservableQuery when subscribing if notifyOnNetworkStatusChange is set to true.

  • #12512 e809b71 Thanks @jerelmiller! - notifyOnNetworkStatusChange now defaults to true. This means that loading states will be emitted (core API) or rendered (React) by default when calling refetch, fetchMore, etc. To maintain the old behavior, set notifyOnNetworkStatusChange to false in defaultOptions.

    new ApolloClient({
      defaultOptions: {
        watchQuery: {
          // Use the v3 default
          notifyOnNetworkStatusChange: false,
        },
      },
    });

Patch Changes

  • #12536 e14205a Thanks @jerelmiller! - The returned networkStatus in useLazyQuery is now set to setVariables when calling the useLazyQuery execute function for the first time with variables.

  • #12536 e14205a Thanks @jerelmiller! - Ensure ObservableQuery stops polling if switching to a standby fetchPolicy. When switching back to a non-standby fetchPolicy, polling will resume.

  • #12536 e14205a Thanks @jerelmiller! - Ensure a loading state is emitted when calling the execute function after changing clients in useLazyQuery.

  • #12542 afb4fce Thanks @jerelmiller! - Ensure useLazyQuery does not return a partial property which is not specified by the result type.

v4.0.0-alpha.8

10 Apr 17:56
9b15b9b
Compare
Choose a tag to compare
v4.0.0-alpha.8 Pre-release
Pre-release

Major Changes

  • #12539 dd0d6d6 Thanks @jerelmiller! - onError link now uses a single error property to report the error that caused the link callback to be called. This will be an instance of CombinedGraphQLErrors 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 the onError and setOnError methods from ApolloLink. onError was only used by MockLink to rewrite errors if setOnError was used.

  • #12531 7784b46 Thanks @jerelmiller! - Mocked responses passed to MockLink now accept a callback for the request.variables option. This is used to determine if the mock should be matched for a set of request variables. With this change, the variableMatcher option has been removed in favor of passing a callback to variables. Update by moving the callback function from variableMatcher to request.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 to MockLink.

  • #12532 ae0dcad Thanks @jerelmiller! - Default the delay for all mocked responses passed to MockLink using realisticDelay. 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! - Remove newData option for mocked responses passed to MockLink or the mocks option on MockedProvider. This option was undocumented and was nearly identical to using the result option as a callback.

    To replicate the old behavior of newData, use result as a callback and add the maxUsageCount option with a value set to Number.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 to MockLink to accept a callback for the delay option. The delay 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 new realisticDelay helper function for use with the delay callback for mocked responses used with MockLink. realisticDelay will generate a random value between 20 and 50ms to provide an experience closer to unpredictable network latency. realisticDelay can be configured with a min and max 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 default delay for all mocked responses passed to MockLink. This delay can be configured globally (all instances of MockLink will use the global defaults), or per-instance (all mocks in a single instance will use the defaults). A delay 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

10 Apr 17:19
616cb01
Compare
Choose a tag to compare

Patch Changes

  • #12540 0098932 Thanks @phryneas! - Refactor: Move notification scheduling logic from QueryInfo to ObservableQuery

  • #12540 0098932 Thanks @phryneas! - Refactored cache emit logic for ObservableQuery. This should be an invisible change.

v3.13.6

04 Apr 16:13
949bd14
Compare
Choose a tag to compare

Patch Changes

  • #12285 cdc55ff Thanks @phryneas! - keep ObservableQuery created by useQuery non-active before it is first subscribed

v4.0.0-alpha.7

03 Apr 18:51
e794dd8
Compare
Choose a tag to compare
v4.0.0-alpha.7 Pre-release
Pre-release

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

  • #12513 9c3207c Thanks @phryneas! - Removed the parser cache. The functionality has been replaced in a way that doesn't need caching.

v4.0.0-alpha.6

01 Apr 20:11
4665b0c
Compare
Choose a tag to compare
v4.0.0-alpha.6 Pre-release
Pre-release

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! - Remove loading, networkStatus, and partial 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 a data property to CombinedGraphQLErrors that captures any partial data returned by the GraphQL response when errors are also returned.

  • #12488 c98b633 Thanks @phryneas! - Add a new method for static SSR of React components, prerenderStatic.
    The old methods, getDataFromTree, getMarkupFromTree and renderToStringWithData
    have been deprecated in favor of prerenderStatic.

    If used with React 19 and the prerender or prerenderToNodeStream apis from
    react-dom/static, this method can now be used to SSR-prerender suspense-enabled
    hook APIs.

v4.0.0-alpha.5

31 Mar 16:57
3f61b7d
Compare
Choose a tag to compare
v4.0.0-alpha.5 Pre-release
Pre-release

Major Changes

  • #12478 5ea6a45 Thanks @jerelmiller! - Remove variables from the result returned from useSubscription.

  • #12476 6afff60 Thanks @jerelmiller! - Subscriptions now emit a SubscribeResult instead of a FetchResult. As a result, the errors field has been removed in favor of error.

  • #12475 3de63eb Thanks @jerelmiller! - Unify error behavior on mutations for GraphQL errors and network errors by ensuring network errors are subject to the errorPolicy. Network errors created when using an errorPolicy of all will now resolve the promise and be returned on the error property of the result, or stripped away when the errorPolicy is none.

  • #12475 3de63eb Thanks @jerelmiller! - client.mutate now returns a MutateResult instead of FetchResult. As a result, the errors property has been removed in favor of error which is set if either a network error occured or GraphQL errors are returned from the server.

    useMutation now also returns a MutateResult instead of a FetchResult.

  • #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 the errorPolicy. Network errors that terminate the connection will now be emitted on the error property passed to the next callback followed by a call to the complete callback.

  • #12478 5ea6a45 Thanks @jerelmiller! - Remove deprecated onSubscriptionData and onSubscriptionComplete callbacks from useSubscription. Use onData and onComplete instead.

  • #12476 6afff60 Thanks @jerelmiller! - GraphQL errors or network errors emitted while using an errorPolicy of ignore in subscriptions will no longer emit a result if there is no data emitted along with the error.

  • #12476 6afff60 Thanks @jerelmiller! - Subscriptions no longer emit errors in the error callback and instead provide errors on the error property on the result passed to the next 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 an error property followed by a complete event instead.

Minor Changes

Patch Changes

  • #12487 b695e5e Thanks @phryneas! - useQuery with ssr: false - previously, skip had a higher priortity than ssr: false while ssr: false had a higher priority than fetchPolicy: "standby" (which is roughly equivalent to skip).

    This priority has been adjusted so now both skip and fetchPolicy: "standby" have a higher priority than ssr: false and will return loading: false, while ssr: false will only come after those and will return loading: true if those are not set.

  • #12475 3de63eb Thanks @jerelmiller! - Fix an issue where passing onError to useMutation would resolve the promise returned by the mutate function instead of rejecting when using an errorPolicy of none.

  • #12475 3de63eb Thanks @jerelmiller! - Fix an issue where additional response properties were returned on the result returned from client.mutate, such as @defer payload fields. These properties are now stripped out to correspond to the TypeScript type.

v4.0.0-alpha.4

24 Mar 19:32
3f384a9
Compare
Choose a tag to compare
v4.0.0-alpha.4 Pre-release
Pre-release

Major Changes

  • #12463 3868df8 Thanks @jerelmiller! - ObservableQuery.setOptions has been removed as it was an alias of reobserve. Prefer using reobserve 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. The newNetworkStatus argument has been removed to facilitate this change.

  • #12470 d32902f Thanks @phryneas! - ssrMode, ssrForceFetchDelay and disableNetworkFetches have been reworked:

    Previously, a ObservableQuery created by client.query or client.watchQuery
    while one of those were active would permanently be changed from a fetchPolicy
    of "network-only" or "cache-and-network" to "cache-first", and stay that way
    even long after disableNetworkFetches would have been deactivated.

    Now, the ObservableQuery will keep their original fetchPolicy, but queries
    made during disableNetworkFetches will just apply the fetchPolicy replacement
    at request time, just for that one request.

    ApolloClient.disableNetworkFetches has been renamed to ApolloClient.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 returns reobserve as part of its result. It was possible to use reobserve to set new options on the underlying ObservableQuery 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 exports useQuery.Options and useQuery.Result types. As such, the old hook types have been deprecated and will be removed in v5.