Skip to content

Commit

Permalink
Merge pull request #7075 from apollographql/7071-no-warning-for-scala…
Browse files Browse the repository at this point in the history
…r-field-update

Avoid "Cache data may be lost..." warnings when updating scalar fields.
  • Loading branch information
benjamn authored Sep 25, 2020
2 parents 91299cc + 901bb18 commit 3caa496
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 2 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
- Shallow-merge `options.variables` when combining existing or default options with newly-provided options, so new variables do not completely overwrite existing variables. <br/>
[@amannn](https://github.com/amannn) in [#6927](https://github.com/apollographql/apollo-client/pull/6927)

- Avoid displaying `Cache data may be lost...` warnings for scalar field values that happen to be objects, such as JSON data. <br/>
[@benjamn](https://github.com/benjamn) in [#7075](https://github.com/apollographql/apollo-client/pull/7075)

## Apollo Client 3.2.1

## Bug Fixes
Expand Down
34 changes: 34 additions & 0 deletions src/cache/inmemory/__tests__/__snapshots__/writeToStore.ts.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,39 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`writing to the store "Cache data maybe lost..." warnings should not warn when scalar fields are updated 1`] = `
Object {
"ROOT_QUERY": Object {
"__typename": "Query",
"currentTime({\\"tz\\":\\"UTC-5\\"})": Object {
"localeString": "9/25/2020, 1:08:33 PM",
},
"someJSON": Object {
"foos": Array [
"bar",
"baz",
],
"oyez": 3,
},
},
}
`;
exports[`writing to the store "Cache data maybe lost..." warnings should not warn when scalar fields are updated 2`] = `
Object {
"ROOT_QUERY": Object {
"__typename": "Query",
"currentTime({\\"tz\\":\\"UTC-5\\"})": Object {
"msSinceEpoch": 1601053713081,
},
"someJSON": Object {
"asdf": "middle",
"qwer": "upper",
"zxcv": "lower",
},
},
}
`;
exports[`writing to the store user objects should be able to have { __typename: "Mutation" } 1`] = `
Object {
"Gene:{\\"id\\":\\"SLC45A2\\"}": Object {
Expand Down
66 changes: 66 additions & 0 deletions src/cache/inmemory/__tests__/writeToStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1582,6 +1582,72 @@ describe('writing to the store', () => {
});
});

describe('"Cache data maybe lost..." warnings', () => {
const { warn } = console;
let warnings: any[][] = [];

beforeEach(() => {
warnings.length = 0;
console.warn = (...args: any[]) => {
warnings.push(args);
};
});

afterEach(() => {
console.warn = warn;
});

it("should not warn when scalar fields are updated", () => {
const cache = new InMemoryCache;

const query = gql`
query {
someJSON
currentTime(tz: "UTC-5")
}
`;

expect(warnings).toEqual([]);

const date = new Date(1601053713081);

cache.writeQuery({
query,
data: {
someJSON: {
oyez: 3,
foos: ["bar", "baz"],
},
currentTime: {
localeString: date.toLocaleString("en-US", {
timeZone: "America/New_York",
}),
},
},
});

expect(cache.extract()).toMatchSnapshot();
expect(warnings).toEqual([]);

cache.writeQuery({
query,
data: {
someJSON: {
qwer: "upper",
asdf: "middle",
zxcv: "lower",
},
currentTime: {
msSinceEpoch: date.getTime(),
},
},
});

expect(cache.extract()).toMatchSnapshot();
expect(warnings).toEqual([]);
});
});

describe('writeResultToStore shape checking', () => {
const query = gql`
query {
Expand Down
16 changes: 14 additions & 2 deletions src/cache/inmemory/writeToStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -284,15 +284,27 @@ export class StoreWriter {
}

if (process.env.NODE_ENV !== "production") {
const hasSelectionSet = (storeFieldName: string) =>
fieldsWithSelectionSets.has(fieldNameFromStoreName(storeFieldName));
const fieldsWithSelectionSets = new Set<string>();
workSet.forEach(selection => {
if (isField(selection) && selection.selectionSet) {
fieldsWithSelectionSets.add(selection.name.value);
}
});

const hasMergeFunction = (storeFieldName: string) => {
const childTree = mergeTree.map.get(storeFieldName);
return Boolean(childTree && childTree.info && childTree.info.merge);
};

Object.keys(incomingFields).forEach(storeFieldName => {
// If a merge function was defined for this field, trust that it
// did the right thing about (not) clobbering data.
if (!hasMergeFunction(storeFieldName)) {
// did the right thing about (not) clobbering data. If the field
// has no selection set, it's a scalar field, so it doesn't need
// a merge function (even if it's an object, like JSON data).
if (hasSelectionSet(storeFieldName) &&
!hasMergeFunction(storeFieldName)) {
warnAboutDataLoss(
entityRef,
incomingFields,
Expand Down

0 comments on commit 3caa496

Please sign in to comment.