0

I have a datasheet style table with list of records, that need updating their values. I would like to run a single Submit and in my GraphQL send an array of records as a single argument to the set query. They are actually MongoDB documents. As in the title I am using React with Apollo client. Thank you in advance :)

More details below

So I have this mutation on server side it works with Playground. However it gives errors on Apollo client side.

mutation { updateWorklogs( input: [ { id: "60c6b", week1: 1, week2: 2, week4: 9 }, { id: "60c6c", week1: 3, week2: 4, week4: 1.5 } ] ) { id year month name } }

Apollo Client tools show the mutation variables correctly as

tools showing

However in Apollo Client tools when I try to run the query it is showing as {“input”:[{“id”:“60c6b9ca277c815ec200992a”,“week1”:5,“week2”:2,“week3”:0,“week4”:9},{“id”:“60c6ba80277c815ec200992e”,“week1”:0,“week2”:5,“week3”:0,“week4”:0}]}

which I guess is fine. This should work as it is identical to what I'm running in Playground, but not!

I tried to run JSON.parse(myVariables) but no help. Apollo seems to convert it. And final result the query doesn’t run. It returns a 400 response, with not much else. If I need an interface I'm not using TS, no idea how to do it in React JS yet.

const [setWorklog] = useMutation(SET_WORKLOGS);

const handleSubmit = (event) => {
    event.preventDefault();
    console.log("state=", state) // returns the above state, which is correct
    setWorklog({ variables: { input: state }, update(proxy, result) {
      const data = proxy.readQuery({
        query: GET_WORKLOGS
      })
      data.userWorklogs = result.data.setWorklogs;
      proxy.writeQuery({ query: GET_WORKLOGS, data });
    }}).then(
      console.log("returned=",data.updateWorklogs)
    )
    .catch(e => {
      console.log("Error=", e);
    })
  };

Thanks again

Cem
  • 1
  • 1
  • 3
  • multiple, separated mutation (batching?) or one mutation with complex args? does API support this? tested in playground? – xadm Jun 18 '21 at 11:06
  • Yes thank you xadm. It is set as a single mutation with many records passed as an array argument. I am passing the mongo id and week1, week2, week3, week4 per record, so the API should do all the updates. It is tested on playground and works well. In React I have a state variable that holds all the records. OnChange I can update the state array of records using immer, but I need a separate one for gql variables as well and struggling to make it work. Constantly hitting problems on updating the variables and the Apollo cache. Constantly breaking with index.js errors that gives no information. – Cem Jun 18 '21 at 11:18
  • details!! ... show tested mutation (using query variables, of course), input type defs, etc. – xadm Jun 18 '21 at 11:37
  • It seems too long here as I mentioned the API is working. If you would like to see it for yourself. I would be happy to share. My issue is in React part using functional components and setting the state providing variables to the mutation and sending it. State is an array of objects. Updating each individual object property is the challenge so far, and binding it with the data field. – Cem Jun 18 '21 at 15:37
  • update the question, of course – xadm Jun 18 '21 at 15:50
  • Hi xadm, thanks, you seem to know your stuff. Can't find any article regarding passing array of objects. Above I have added all details. Let me know if you need anything else. – Cem Jun 20 '21 at 16:57
  • I don't care about client tools ... how used in react? ... `useMutation`? check/show network request body example – xadm Jun 20 '21 at 17:15
  • I just added the useMutation call from handleSubmit. Hope it helps. The GraphQL query is also included above. – Cem Jun 20 '21 at 22:02
  • mutation/query with variables has different syntax - https://graphql.org/learn/queries/#variables - modify and test in playground ... and again, **check network request body** (json) - probably `variables:{input:{input` - compare with playground (**using variables**, of course) – xadm Jun 20 '21 at 22:48

1 Answers1

0

Thank you xadm, This is now solved. And no need to use gqlast. Just make sure in these types of queries you always include the top section alias for defining types. It's not specified anywhere, but you can even use the input type you declared on your server. Then make sure your declared input: $input matches as below. This feature is an amazing GraphQL feature, updating a whole table grid with a single mutation. It is not possible with REST API's. And you can return the updated results, meaning you don't have to do another trip to refetch.

 mutation updateWorklogs(
    $input: [updateWorklogInput]
  ) {
    updateWorklogs(
      input: $input
    ) {
      id
      projectId
      name
      year
      month
      week1
      week2
      week3
      week4
      totalMonth
      totalProject
    }
  }

//Define
const [setWorklog] = useMutation(SET_WORKLOGS);

// Use it like this 
  const handleSubmit = (event) => {
    event.preventDefault();
    setWorklog({ variables: { input: input })
    .catch(e => {
      console.log("Error=", e);
    })
  };
Cem
  • 1
  • 1
  • 3
  • *' you can even use the input type you declared on your server'* - you **should** use the type defined at server :D ... arg not accepted if not matches type – xadm Jun 21 '21 at 22:50