How to access Apollo useMutaion response/payload

When I do a mutation with useMutation hook, I can console.log my data but I cannot save the data object in a localState. I don’t know what am I missing. Any help is appreciated.

My code is as follows:

//Schema file

startTest(identifier: String): TestResponse

the mutation payload is as follows:

  type TestResponse {
    errorCode: Int
    errorMessage: String
    success: Boolean
    transactionId: ID
    version: Int
  }

In the resolver I hardcoded the following data return:

    startTest(_, { identifier }) {
      console.log("hello from server");
      return {
        errorCode: 0,
        errorMessage: null,
        success: true,
        transactionId: "d2984911-bbc4-4e6a-9103-96ca934f6ed3",
        version: 0,
      };
    },

In component folder I’ve triggered the mutation with a button click.

const [startTestt, { loading, error, data }] = useMutation(
    START_FIRE_DAMPER_TEST,
    {
      onCompleted: ({ startFireDampersTest }) =>
        console.log(startFireDampersTest.success),
        useState(startFireDampersTest.success)
       
    },

    {
      onError: () => console.log("error!"), // never gets called
    }
  );

  console.log(result); // undefined

  if (loading) return <p>Loading...</p>;
  if (error) return <p>Error!</p>;

  if (data && data.startFireDampersTest)
    return (
      <div>
        <p>Success!</p>
        <pre>{JSON.stringify(data, null, 2)}</pre> // I can see string object but how to render the element of the object inside the component??
      </div>
    );


  const triggerTest = () => {
    startTest({ variables: { identifier: "0000000" } });
  };

  return (
    <>
      <Banner />
       <button onClick={triggerTest}>Click to Delete Buck</button>

    </>
  );

I need to access returned data returned from mutation for later use. the test response/payload is not related to any other queries or types to update. It just contains status of the test and other key values that I need to save in a local state or maybe render it inside a component.

Hello! A few initial thoughts:

  • I see in your useMutation call that your mutate function is named startTestt (extra t). Could just be a typo after pasting, but pointing out in case this is a quick fix.

  • With console.log(result), there doesn’t appear to be a result object in scope. You could console.log(data) there if you want to see the mutation result’s data after the mutation completes and the component re-renders.

  • By default, Apollo Client’s normalized cache works best if every returned object includes an id to uniquely identify an object of that type (see the docs). Adding an id field to TypeResponse or specifying another identifying field might help make your mutation results more readily available.

  • Which fields are you requesting in START_FIRE_DAMPER_TEST? Make sure you’re including all of the fields you need in the mutation body:

mutation StartTest(variables) {
  startTest(arguments) {
    errorCode
    errorMessage
    ...other fields...
  }
}
1 Like

Thank you so much for your answer Stephen.

Actually this typo was only in this question, but in my actual code it is working fine.

Maybe I couldn’t explain my question well.

the question is not about how to get the data, since I am already getting it successfully.
I have refactored the code below for more clarity.

what is happening:

1- the mutation test on onClick button is working.
2- When I am consoling the data.startTest.success, I see the success message i set in the mutation resolver return object. but i cannot render this message inside JSX. (it keeps saying success is not defined)

the only way i was able to see the data is with this trick:

<p>{JSON.stringify(data, null, 2)}</p>

What I want to do is once the the button clicked I want to render the data on the screen. for example a message to the UI that says test is success and a div to render the returned object data inside.

<div>
  <p>test is success</p>
  <div>
    {data.startTest.success}
   </div>
</div>

/////////////////////////////////////////// server \\\\\\\\\\\\\\\\\\\\\\

Schema:

  type TestPayload {
    errorCode: Int
    errorMessage: String
    success: Boolean
    transactionId: ID
    version: Int
  }


# Mutation 

  type Mutation {
    startTest(identifier: String): TestPayload
  }
`;

resolver:

startTest(_, { identifier }) {
      console.log("hello from server");
      return {
        errorCode: 0,
        errorMessage: null,
        success: true,
        transactionId: "d2984911-bbc4-4e6a-0000-96ca934f6ed3",
        version: 0,
      };
    },

/////////////////////////////////////////// Client \\\\\\\\\\\\\\\\\\\\\\

Mutation:

export const START_TEST = gql`
  mutation StartTest($identifier: String) {
    startTest(identifier: $identifier) {
      errorCode
      errorMessage
      success
      transactionId
      version
    }
  }
`;

Starting the Test Mutation onClick inside a component

const DataTables = () => {
const [result, setResult] = useState(null);

const [startTest, { data, loading, error }] = useMutation(
START_TEST,

{

onCompleted: (data) => {
console.log(data.startTest.success);
},

{
  onError: () => console.log("error!"), // never gets called
}

);

const triggerTest = () => {
startTest({ variables: { identifier: “0000000” } });
};

return (
<>


<button onClick={triggerTest }>

    <GroupsTable />
    <FireDampersTable />
    <SmokeDetectorsTable />
  </div>
</>

);
};

export default DataTables;


Thank you in advance for your answers.