Skip to content

Commit

Permalink
Prevent fragments from impacting @client fields
Browse files Browse the repository at this point in the history
In the `LocalState.resolveSelectionSet` method, we’re adding the
`rootValue` to the `resultsToMerge` array multiple times. This
is causing issues when a `@client` query, that also includes
fragments,  is run. If the `@client` field is configured to use a
local resolver, when the result is calculated and returned from
the local resolver, the fragment results are then merged with the
result, along with another copy of the `rootValue`. The second
copy of the `rootValue` overrides the value received from the
`@client` local resolver.

This commit moves the merging of the `rootValue` up a level, so
it only happens once, and doesn’t override local resolver results.
  • Loading branch information
hwillson committed Feb 22, 2019
1 parent b781f78 commit b5bafd0
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 2 deletions.
60 changes: 60 additions & 0 deletions packages/apollo-client/src/__tests__/local-state/resolvers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,66 @@ describe('Basic resolver capabilities', () => {
done();
});
});

it(
'should resolve @client fields using local resolvers and not have ' +
'their value overridden when a fragment is loaded',
() => {
const query = gql`
fragment LaunchDetails on Launch {
id
__typename
}
query Launch {
launch {
isInCart @client
...LaunchDetails
}
}
`;

const link = new ApolloLink(() =>
Observable.of({
data: {
launch: {
id: 1,
__typename: 'Launch',
},
},
}),
);

const client = new ApolloClient({
cache: new InMemoryCache(),
link,
resolvers: {
Launch: {
isInCart() {
return true;
},
},
},
});

client.writeData({
data: {
launch: {
isInCart: false,
__typename: 'Launch',
},
},
});

return client.query({ query }).then(({ data }) => {
expect(data.launch.isInCart).toBe(true);
}).then(() => {
client.query({ query }).then(({ data }) => {
expect(data.launch.isInCart).toBe(true);
});
});
}
);
});

describe('Writing cache data from resolvers', () => {
Expand Down
4 changes: 2 additions & 2 deletions packages/apollo-client/src/core/LocalState.ts
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,7 @@ export class LocalState<TCacheShape> {
rootValue,
execContext,
).then(result => ({
result,
result: mergeDeep(rootValue, result),
exportedVariables: execContext.exportedVariables,
}));
}
Expand All @@ -357,7 +357,7 @@ export class LocalState<TCacheShape> {
execContext: ExecContext,
) {
const { fragmentMap, context, variables } = execContext;
const resultsToMerge: TData[] = [rootValue];
const resultsToMerge: TData[] = [];

const execute = async (selection: SelectionNode): Promise<void> => {
if (!shouldInclude(selection, variables)) {
Expand Down

0 comments on commit b5bafd0

Please sign in to comment.