diff --git a/Changelog.md b/Changelog.md index 0f7fcf19e3..24085b18b4 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,7 @@ first three params (`TChildProps` can be derived). [#1402](https://github.com/ap - Rename `getDataFromTree` type `QueryResult` to `QueryTreeResult` [#1467](https://github.com/apollographql/react-apollo/pull/1467) - Rename type `QueryProps` to `GraphqlQueryControls` [#1467](https://github.com/apollographql/react-apollo/pull/1467) [#1478](https://github.com/apollographql/react-apollo/pull/1478) - Remove re-export of `compose` (a.k.a. `lodash/flowright`) as it is loses types (exports as `any`). Users may choose to use `lodash/flowright` or `recompose/compose` themselves based on their use case. [#1478](https://github.com/apollographql/react-apollo/pull/1478) + - Remove deprecated [`options.updateQueries`](https://www.apollographql.com/docs/react/basics/mutations.html#graphql-mutation-options-updateQueries), use [`options.update`](https://www.apollographql.com/docs/react/basics/mutations.html#graphql-mutation-options-update) instead [#1485](https://github.com/apollographql/react-apollo/pull/1485) - **Other Changes** - Update all dependencies, scripts' usage, prettier and typescript setup [#1402](https://github.com/apollographql/react-apollo/pull/1402) diff --git a/src/index.js.flow b/src/index.js.flow index d48fcc62c2..fe63c5e971 100644 --- a/src/index.js.flow +++ b/src/index.js.flow @@ -51,7 +51,6 @@ export type DefaultChildProps = ChildProps; export interface MutationOpts { variables?: Object; optimisticResponse?: Object; - updateQueries?: MutationQueryReducersMap<*>; refetchQueries?: string[] | PureQueryOptions[]; update?: MutationUpdaterFn<*>; } diff --git a/src/queryRecycler.ts b/src/queryRecycler.ts index 109add8b66..40caf0898e 100644 --- a/src/queryRecycler.ts +++ b/src/queryRecycler.ts @@ -17,7 +17,7 @@ interface ObservableQueryItem { * * Recycling observable queries avoids a few unexpected functionalities that * may be hit when using the `react-apollo` API. Namely not updating queries - * when a component unmounts, and calling reducers/`updateQueries` more times + * when a component unmounts, and calling reducers/`update` more times * then is necessary for old observable queries. * * We assume that the GraphQL document for every `ObservableQuery` is the same. diff --git a/src/types.ts b/src/types.ts index abe2c37de7..61ccdac46f 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,4 @@ import ApolloClient, { - MutationQueryReducersMap, ApolloQueryResult, ApolloError, FetchPolicy, @@ -20,7 +19,6 @@ export type OperationVariables = { export interface MutationOpts { variables?: TGraphQLVariables; optimisticResponse?: Object; - updateQueries?: MutationQueryReducersMap; refetchQueries?: string[] | PureQueryOptions[]; update?: MutationUpdaterFn; client?: ApolloClient; diff --git a/test/client/graphql/mutations/queries.test.tsx b/test/client/graphql/mutations/queries.test.tsx index 8d6c3acc1c..3580e214e1 100644 --- a/test/client/graphql/mutations/queries.test.tsx +++ b/test/client/graphql/mutations/queries.test.tsx @@ -74,6 +74,20 @@ describe('graphql(mutation) query integration', () => { }); it('allows for updating queries from a mutation', done => { + const query = gql` + query todos { + todo_list { + id + title + tasks { + id + text + completed + } + } + } + `; + const mutation = gql` mutation createTodo { createTodo { @@ -100,44 +114,21 @@ describe('graphql(mutation) query integration', () => { }, }; - const updateQueries = { - todos: (previousQueryResult, { mutationResult, queryVariables }) => { - if (queryVariables.id !== '123') { - // this isn't the query we updated, so just return the previous result - return previousQueryResult; - } - // otherwise, create a new object with the same shape as the - // previous result with the mutationResult incorporated - const originalList = previousQueryResult.todo_list; - const newTask = mutationResult.data.createTodo; - return { - todo_list: Object.assign(originalList, { - tasks: [...originalList.tasks, newTask], - }), - }; - }, + const update = (proxy, { data: { createTodo } }) => { + const data = proxy.readQuery({ query }); // read from cache + data.todo_list.tasks.push(createTodo); // update value + proxy.writeQuery({ query, data }); // write to cache }; - const query = gql` - query todos($id: ID!) { - todo_list(id: $id) { - id - title - tasks { - id - text - completed - } - } - } - `; - - const data = { + const expectedData = { todo_list: { id: '123', title: 'how to apollo', tasks: [] }, }; const link = mockSingleLink( - { request: { query, variables: { id: '123' } }, result: { data } }, + { + request: { query, variables: { id: '123' } }, + result: { data: expectedData }, + }, { request: { query: mutation }, result: { data: mutationData } }, ); const cache = new Cache({ addTypename: false }); @@ -146,7 +137,7 @@ describe('graphql(mutation) query integration', () => { let count = 0; @graphql(query) @graphql(mutation, { - options: () => ({ optimisticResponse, updateQueries }), + options: () => ({ optimisticResponse, update }), }) class Container extends React.Component { componentWillReceiveProps(props) { diff --git a/test/client/graphql/mutations/recycled-queries.test.tsx b/test/client/graphql/mutations/recycled-queries.test.tsx index 8127d3621a..b594fbca46 100644 --- a/test/client/graphql/mutations/recycled-queries.test.tsx +++ b/test/client/graphql/mutations/recycled-queries.test.tsx @@ -9,7 +9,7 @@ import stripSymbols from '../../../test-utils/stripSymbols'; describe('graphql(mutation) update queries', () => { // This is a long test that keeps track of a lot of stuff. It is testing - // whether or not the `updateQueries` reducers will run even when a given + // whether or not the `options.update` reducers will run even when a given // container component is unmounted. // // It does this with the following procedure: @@ -27,8 +27,22 @@ describe('graphql(mutation) update queries', () => { // // There are also a lot more assertions on the way to make sure everything is // going as smoothly as planned. - it('will run `updateQueries` for a previously mounted component', () => + it('will run `update` for a previously mounted component', () => new Promise((resolve, reject) => { + const query = gql` + query todos { + todo_list { + id + title + tasks { + id + text + completed + } + } + } + `; + const mutation = gql` mutation createTodo { createTodo { @@ -48,47 +62,22 @@ describe('graphql(mutation) update queries', () => { }; let todoUpdateQueryCount = 0; - - const updateQueries = { - todos: (previousQueryResult, { mutationResult, queryVariables }) => { - todoUpdateQueryCount++; - - if (queryVariables.id !== '123') { - // this isn't the query we updated, so just return the previous result - return previousQueryResult; - } - // otherwise, create a new object with the same shape as the - // previous result with the mutationResult incorporated - const originalList = previousQueryResult.todo_list; - const newTask = mutationResult.data.createTodo; - return { - todo_list: Object.assign(originalList, { - tasks: [...originalList.tasks, newTask], - }), - }; - }, + const update = (proxy, { data: { createTodo } }) => { + todoUpdateQueryCount++; + const data = proxy.readQuery({ query }); // read from cache + data.todo_list.tasks.push(createTodo); // update value + proxy.writeQuery({ query, data }); // write to cache }; - const query = gql` - query todos($id: ID!) { - todo_list(id: $id) { - id - title - tasks { - id - text - completed - } - } - } - `; - - const data = { + const expectedData = { todo_list: { id: '123', title: 'how to apollo', tasks: [] }, }; const link = mockSingleLink( - { request: { query, variables: { id: '123' } }, result: { data } }, + { + request: { query, variables: { id: '123' } }, + result: { data: expectedData }, + }, { request: { query: mutation }, result: { data: mutationData } }, { request: { query: mutation }, result: { data: mutationData } }, ); @@ -99,8 +88,8 @@ describe('graphql(mutation) update queries', () => { let mutate; - @graphql(mutation, { options: () => ({ updateQueries }) }) - class Mutation extends React.Component { + @graphql(mutation, { options: () => ({ update }) }) + class MyMutation extends React.Component { componentDidMount() { mutate = this.props.mutate; } @@ -115,7 +104,7 @@ describe('graphql(mutation) update queries', () => { let queryRenderCount = 0; @graphql(query) - class Query extends React.Component { + class MyQuery extends React.Component { componentWillMount() { queryMountCount++; } @@ -203,13 +192,13 @@ describe('graphql(mutation) update queries', () => { const wrapperMutation = renderer.create( - + , ); const wrapperQuery1 = renderer.create( - + , ); @@ -232,7 +221,7 @@ describe('graphql(mutation) update queries', () => { setTimeout(() => { const wrapperQuery2 = renderer.create( - + , );