1

Basically I have an array of objects and based from that array's length, I need to do a mutation for each instance like so:

arrayOfObjects.forEach((object) => {
  someGraphQlMutation({
    variables: object.id,
  });
});

-----------------

const [someGraphQlMutation] = useMutation(
    SOME_GRAPHQL_MUTATION,
    {
        onCompleted: (data) => {
            // callback
        }
    }
);

However, after all the mutations are done, I need to call another function. I need to wait for the iteration mutations to finish before calling the callback function. Am I able to use Promise.all in this context?

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
catandmouse
  • 11,309
  • 23
  • 92
  • 150
  • Technically, you could just create a single mutation that has all the queries you need, but `useMutation` sounds like a `hook`, so no, you can't use `Promise.all` in this case – goto Jul 17 '20 at 11:06
  • This pattern should be avoided due to repeated network roundtrips and cumulative latency (not to mention the complexity of error handling when one of the mutations fails but they were intended to be performed as a group). Create a new mutation that accepts an array and handles the iteration on the server. – Michel Floyd Jan 13 '22 at 01:46

1 Answers1

1

Yes, you can use Promise.all to await all the mutations:

const [someGraphQlMutation] = useMutation(SOME_GRAPHQL_MUTATION);
const doEverything = async () => {
  try {
    const results = await Promise.all(arrayOfObjects.map(object => {
      return someGraphQlMutation({ variables: object.id });
    }));
    // results will be an array of execution result objects (i.e. { data, error })
    // Do whatever here with the results
  } catch (e) {
    // Handle any errors as appropriate
  }
}
Daniel Rearden
  • 80,636
  • 11
  • 185
  • 183