Skip to content

Commit

Permalink
deprecate useFragement returnPartialData option (#10764)
Browse files Browse the repository at this point in the history
Co-authored-by: Lenz Weber-Tronic <lenz@apollographql.com>
Co-authored-by: Jerel Miller <jerelmiller@gmail.com>
  • Loading branch information
3 people committed May 3, 2023
1 parent 439ab9b commit 1b0a61f
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 2 deletions.
5 changes: 5 additions & 0 deletions .changeset/brave-buttons-grab.md
@@ -0,0 +1,5 @@
---
"@apollo/client": patch
---

Deprecate `useFragment` `returnPartialData` option
90 changes: 90 additions & 0 deletions src/react/hooks/__tests__/useFragment.test.tsx
Expand Up @@ -911,4 +911,94 @@ describe("useFragment", () => {
]);
});
});

describe("tests with incomplete data", () => {
let cache: InMemoryCache, wrapper: React.FunctionComponent;
const ItemFragment = gql`
fragment ItemFragment on Item {
id
text
}
`;

beforeEach(() => {
cache = new InMemoryCache();

wrapper = ({ children }: any) => <MockedProvider cache={cache}>{children}</MockedProvider>;

// silence the console for the incomplete fragment write
const spy = jest.spyOn(console, 'error').mockImplementation(() => {});
cache.writeFragment({
fragment: ItemFragment,
data: {
__typename: "Item",
id: 5,
},
});
spy.mockRestore();
});

it("assumes `returnPartialData: true` per default", () => {
const { result } = renderHook(
() =>
useFragment({
fragment: ItemFragment,
from: { __typename: "Item", id: 5 },
}),
{ wrapper }
);

expect(result.current.data).toEqual({ __typename: "Item", id: 5 });
expect(result.current.complete).toBe(false);
});

it("throws an exception with `returnPartialData: false` if only partial data is available", () => {
// this is actually not intended behavior, but it is the current behavior
// let's document it in a test until we remove `returnPartialData` in 3.8

let error: Error;

renderHook(
() => {
// we can't just `expect(() => renderHook(...)).toThrow(...)` because it will render a second time, resulting in an uncaught exception
try {
useFragment({
fragment: ItemFragment,
from: { __typename: "Item", id: 5 },
returnPartialData: false,
});
} catch (e) {
error = e;
}
},
{ wrapper }
);

expect(error!.toString()).toMatch(`Error: Can't find field 'text' on Item:5 object`);
});

it("throws an exception with `returnPartialData: false` if no data is available", () => {
// this is actually not intended behavior, but it is the current behavior
// let's document it in a test until we remove `returnPartialData` in 3.8
let error: Error;

renderHook(
() => {
// we can't just `expect(() => renderHook(...)).toThrow(...)` because it will render a second time, resulting in an uncaught exception
try {
useFragment({
fragment: ItemFragment,
from: { __typename: "Item", id: 6 },
returnPartialData: false,
});
} catch (e) {
error = e;
}
},
{ wrapper }
);

expect(error!.toString()).toMatch(`Error: Dangling reference to missing Item:6 object`);
});
});
});
13 changes: 11 additions & 2 deletions src/react/hooks/useFragment.ts
Expand Up @@ -20,13 +20,22 @@ extends Omit<
| "query"
| "optimistic"
| "previousResult"
>, Omit<
Cache.ReadFragmentOptions<TData, TVars>,
| "returnPartialData"
>, Omit<Cache.ReadFragmentOptions<TData, TVars>,
| "id"
| "returnPartialData"
> {
from: StoreObject | Reference | string;
// Override this field to make it optional (default: true).
optimistic?: boolean;

/**
* Whether to return incomplete data rather than null.
* Defaults to `true`.
* @deprecated This option will be removed in Apollo Client 3.8.
* Please check `result.missing` instead.
*/
returnPartialData?: boolean;
}

// Since the above definition of UseFragmentOptions can be hard to parse without
Expand Down

0 comments on commit 1b0a61f

Please sign in to comment.