How to do Batch Mutations with Apollo Client
Asked Answered
S

2

22

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

Sufi answered 4/5, 2018 at 14:57 Comment(1)
Do you have control over the backend API? Are you able to modify it?Woodcraft
B
1

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!

Barnaby answered 10/9, 2019 at 19:32 Comment(0)
A
0

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.

Alysonalysoun answered 25/5, 2020 at 18:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.