简体   繁体   中英

How to do Batch Mutations with Apollo Client

I try to use ApolloClient 2.1 with the new Mutation Component.

Simple use cases are working but now I have something more complex.

What I want to achieve is to query data and put them in a list, then sort this list (here via react-sortable-hoc) and once sorted, I want to update the new position for all elements in the list.

So the basis is something like this, which is working for simple Querying:

const query = gql`
{
  items( order:{by:"position", direction:"desc"}) {
    id
    name
    position
  }
}`

const ItemView extends Component {
    onSortEnd = ({ oldIndex, newIndex }) => {
       console.log("Sort ended: ", oldIndex, newIndex);
    }

    render() {
     <Query query={query}>
        {({ loading, data, error }) => {
          if (loading) return <p>Loading...</p>;
          if (error) return <p>Error</p>;

          return (
            <ItemList items={data.items} onSortEnd={this.onSortEnd} />
          )
        }}
      </Query>
    }
}

Now I really struggle at a lot of parts in order to do the mutation.

I think I need to wrap the Mutation Component. But how can I provide a GraphQL Query in there, because I want to do batch mutation with a similar query being fired multiple times, such as

mutation {
  updateItem1: updateItem(id: 457092155, input: {position: 1}) {
    item {
      id
    }
    ok 
    errors

  },
  updateItem2: updateItem(id: 54489270, input: {position: 2}) {
    item {
      id
    }
    ok 
    errors

  },
  ... // much more mutations, one for each item in the list
}

So my main question is, how do I pass a GraphQL mutation with dynamic amount of mutations to the Mutation component? Or should I do this completely differently?

Thanks a lot for any hints

You will have to compose multiple Mutations together in order to achieve this. You can use react-adopt for this. They have even addressed this here https://github.com/pedronauck/react-adopt#leading-with-multiple-params .

You can also take a look at the discussion going on here https://github.com/apollographql/react-apollo/issues/1867 and jasonpaulos has an example demonstrating this with hooks

Hi everyone! I believe that the new Apollo hooks, useQuery, useMutation, and useSubscription, adequately address this use case. To demonstrate this, I have converted @Cridda's example that uses react-adopt and modified it to use @apollo/react-hooks here: https://codesandbox.io/s/apollo-and-react-hooks-4vril

This example is by no means perfect, but it serves as a demonstration of how hooks can massively simplify some use cases.

Hope this helps!

I gave an answer here about Apollo Client's original Promise-based API, which may be easier to deal with for performing iterative mutations at a specific point (such as in a callback function). Provided you have the ID's and corresponding positions, you could iterate over the data asynchronously and perform a mutation on each element.

As Hemant mentioned already, the @compose annotation in Apollo 2.1 is the "correct" / conventional way to solve this problem. If that doesn't work for you for whatever reason, there is possibly another cruder/hacky way to accomplish this:

If your Item model has a parent model, you can mutate multiple nodes with one mutation by passing the children in as the array values to the connect / create / update actions.

The unfortunate limitation here is that there is no way to individually identify child nodes to be updated. What I mean is that you can filter child Items to be mutated based on a criteria (like postition = 2) but that will only allow you to mutate the filtered items to the same state; you won't be able to update them differently from one another this way.

If we allow ourselves one more crude step, you can delete the Item nodes that you wish to update before calling the update mutation - this will allow you to call the mutation with all of the updated items under the create: key in the mutation, which will allow you to specify each item to be created. In this way, the number of items you can create is only limited by the size of your request payload.

There are many cases where deleting and creating nodes is unacceptable (as opposed to updating them)...if you use this method then be sure there are no negative side effects to your use case(s) from deleting item data in this way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM