Apollo-client: Validate that the data matches the shape of a query before writing it back into the store

Created on 20 Apr 2017  路  5Comments  路  Source: apollographql/apollo-client

This issue combines the problem described in #973 #1123 #1273 #1293 #1588 #1605

Intended outcome:
Apollo should throw an error or a warning when the returned data from updateQueries or reducer does not match the shape of the query that is intended to be updated.

Actual outcome:
Apollo flushes the data without any warning.

An insight into this problem is here.

Most helpful comment

I think it would be great to explain this explicitly in the docs. It can be a way to prevent this error from being made in the first place (unconsciously or thinking that if you don't want to provide a value, you should omit it 鈥攊nstead of providing a null-like value).

Although it is briefly explained here, I do think it should be documented as well in Updating the Store and Optimistic UI.

@jakelacey2012 would you like to do a PR in react-docs to provide better information in these pages or somewhere else that you think might be useful?

All 5 comments

I don't think we can solve this for 100% of all cases without schema knowledge, but maybe there is a heuristic approach that will work in 99% of the cases, such as comparing the result object before and after, and checking that their shapes are identical?

I've had this issue and if we cannot throw a warning 100% of the time it should at least be documented, I'm not to sure where though?

I think it would be great to explain this explicitly in the docs. It can be a way to prevent this error from being made in the first place (unconsciously or thinking that if you don't want to provide a value, you should omit it 鈥攊nstead of providing a null-like value).

Although it is briefly explained here, I do think it should be documented as well in Updating the Store and Optimistic UI.

@jakelacey2012 would you like to do a PR in react-docs to provide better information in these pages or somewhere else that you think might be useful?

I don't get this. Lets say I have a type:

type File {
        id: String
        format: String
        version: Int
        resourceType: String
        type: String
        createdAt: String
        height: Int
        width: Int
        bytes: Int
        tags: [String]
        url: String
        caption: String
        source: String
        colors: [String]
      }

Then I query a list of this type

const queryFiles = graphql(gql`
  query fileList {
    items: fileList {
      id, url, tags
    }
  }
`);

And then I call a mutation like

const mutation = graphql(gql`
  mutation file($id: String, $token: String) {
    file(id: $id, token: $token) {
      id, url, tags, colors, width, height, createdAt, caption, source, format, bytes
    }
  }
`, {
  props({ ownProps, mutate }) {
    return {
      save: (id) => {
        return mutate({
          variables: { id },
          updateQueries: {
            fileList: (prev, { mutationResult }) => {
              const newData = mutationResult.data.file;
              return {
                ...prev,
                items: [newData, ...prev.items],
              };
            },
          },
        });
      },
    };
  },
});

Is it expected, that items will now be undefined? I've had a very similar scenario where this was the case. The example above does not match it 100%, but it was extremely similar as where I've been querying/mutating the same type, but the query would only have a subset of the mutation fields.

@bkniffler I think const newData has to have all the same keys that the fileList requires. Not any undefined but can be null. That's what I understood from @helfer

Was this page helpful?
0 / 5 - 0 ratings