0

So I have this array this I'm trying to send to graphql in react...

[{…}]
0: {id: 1, customers_top_competitors: 'asdfasd', top_competitors_url: 'https://www.asdfasd.com/', __typename: 'TopCompetitors'}
length: 1
[[Prototype]]: Array(0)

Here's my query...

export const UPDATE_CUSTOMER_COMPETITORS = gql`
  mutation($customer_id: Int, $data: [TopCompetitorsInput]) {
    updateTopCompetitors(customer_id: $customer_id, data: $data)
  }
`;

and my models...

input TopCompetitorsInput {
  TopCompetitorsInputArray: [TopCompetitorsInputElement]
}

input TopCompetitorsInputElement {
  id: Int
  customers_top_competitors: String
  top_competitors_url: String
}

No matter what I try graphql doesn't like the array's index. Comes back with this error...

react_devtools_backend.js:4026 [GraphQL error]: Message: Variable "$data" got invalid value 
{ 0: { id: 1, customers_top_competitors: "asdfasd", top_competitors_url: "https://www.asdfasd.com/", 
__typename: "TopCompetitors" } }; Field "0" is not defined by type TopCompetitorsInput., Location: [object Object], Path: undefined

Appreciate any guidance!

EDIT:

Per @Disco's request here's how I'm getting the array from the database

  let { data: all_data } = useQuery(GET_TOP_COMPETITORS, {
    skip: !state.customers?.selected?.id,
    variables: { customer_id: state.customers?.selected?.id },
  });

  useEffect(() => {
    setcompetitorData(all_data?.getTopCompetitors);
  }, [all_data]);

and a user can add elements to the array...

  const AddCompetitor = () =>
  {
    if(highestCompetitorID){
      //competitorData.push({id: highestCompetitorID, customers_top_competitors: '', top_competitors_url: ''}); 
      setcompetitorData((competitorData) => [...competitorData, {id: highestCompetitorID, customers_top_competitors: '', top_competitors_url: ''}])
      sethighestCompetitorID(competitorData[competitorData.length - 1].id + 1)
    }else {
      //competitorData.push({id: 1, customers_top_competitors: '', top_competitors_url: ''}); 
      setcompetitorData((competitorData) => [...competitorData, {id: 1, customers_top_competitors: '', top_competitors_url: ''}]); 
      sethighestCompetitorID(competitorData[competitorData.length - 1].id + 1)
    }
  }

EDIT 2: here is the result of console.log(JSON.stringify(competitorData));...

[{"id":1,"customers_top_competitors":"sdfasfdfasdfsd","top_competitors_url":"https://www.asdfdfasd.com/","__typename":"TopCompetitors"}]

EDIT 3: Played around with the graphql interface and tried the data like my react is sending. Plus have one that was successful.

enter image description here

enter image description here

Final Edit:

So I found a way to make my code work by passing the array elements 1 by 1. This can't be the best way. But maybe this will help someone else. Here's what worked...

<Button
  color="orange"
  type="submit"
  onClick={() => {
    for(let x = 0; x < competitorData?.length; x++)
    {
      updateCustomerCompetitors({
        variables: {
          customer_id: state.customers?.selected?.id,
          data: omit(competitorData[x], ["__typename"])
        }
      })
    }
  }
}
>
  Submit
</Button>
5
  • If competitorData then you should not push to it directly. setcompetitorData((oldState) => [...oldState, {id: highestCompetitorID, customers_top_competitors: '', top_competitors_url: ''}]) Could just try to print the array before you pass it as data? Printing it as console.log(JSON.stringify(data)) might help in this case. Commented Nov 2, 2022 at 17:44
  • @Disco Updated the question with the output of console.log Commented Nov 2, 2022 at 18:40
  • I have had a problem before when I pass __typename, try to omit that from the object. And as I mentioned below when the data is [{"id":1,"customers_top_competitors":"sdfasfdfasdfsd","top_competitors_url":"https://www.asdfdfasd.com/","__typename":"TopCompetitors"}] Should be of type $data: [TopCompetitorsInputElement] if you do not do anymore with the data Commented Nov 3, 2022 at 9:31
  • @Disco What's weird is if I just send the first element of the array data: omit(competitorData?.[0], ["__typename"]) it passes correctly to graphql. I'm stumped. Commented Nov 3, 2022 at 17:04
  • 1
    If you are using Apollo you could use apollo playground to get a overview of your mutations and queries and test them manually. Would probably help you in this case. I dont know if I can add anymore to this issue. Hope that you can solve it Commented Nov 4, 2022 at 9:09

1 Answer 1

2

In your code you say that the $data is of the type Array of TopCompetitorsInput which is a object with a field TopCompetitorsInputArray that have a array of TopCompetitorsInputElement as value.

Either change: If you just want to pass on the Array that you have:

export const UPDATE_CUSTOMER_COMPETITORS = gql`
  mutation($customer_id: Int, $data: [TopCompetitorsInputElement]) {
    updateTopCompetitors(customer_id: $customer_id, data: $data)
  }
`;

Or change it to just the input and pass the data as a object

export const UPDATE_CUSTOMER_COMPETITORS = gql`
  mutation($customer_id: Int, $data: TopCompetitorsInput) {
    updateTopCompetitors(customer_id: $customer_id, data: $data)
  }
`;

Per your typings the data input should look like this

{
  TopCompetitorsInputArray: <Your array here>
}
Sign up to request clarification or add additional context in comments.

3 Comments

So I tried your idea of referencing the TopCompetitorInput object. mutation($customer_id: Int, $data: TopCompetitorsInput) but it's still coming back with this error... [GraphQL error]: Message: Variable "$data" got invalid value { 0: { id: 1, customers_top_competitors: "asdfasdf", top_competitors_url: "asdfasd.com", __typename: "TopCompetitors" } } at "data.TopCompetitorsInputArray"; Field "0" is not defined by type TopCompetitorsInputElement., Location: [object Object], Path: undefined
I would then look at you actual data, looks like something is wrong there. Looks like your index of the array becomes the key of a field. Could you post how you create the data array in this case?
thanks for your advice. I've updated my question with how i'm getting the array.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.