MizzyV
MizzyV

Reputation: 11

GraphQL: Call a mutation with objects as inputs

This is the schema.graphql that I have:

type Items @model {
  id: ID!
  ItemName: String!
  ItemDescription: String
  ItemCategory: Categories
  ItemEvents: [Events]
  ItemAttributes: [Attributes]
  createdAt: AWSDateTime
  updatedAt:AWSDateTime
}

type Categories @model {
  id: ID!
  CategoryName: String!
  CategoryItems: [Items]
  createdAt: AWSDateTime
  updatedAt:AWSDateTime
}

the mutation.js created by AWS Amplify looks like this:

export const createItems = /* GraphQL */ `
  mutation CreateItems(
    $input: CreateItemsInput!
    $condition: ModelItemsConditionInput
  ) {
    createItems(input: $input, condition: $condition) {
      id
      ItemName
      ItemDescription
      ItemCategory {
        id
        CategoryName
        CategoryItems {
          id
          ItemName
          ItemDescription
          createdAt
          updatedAt
        }
        createdAt
        updatedAt
      }
      createdAt
      updatedAt
    }
  }
`;

this is where I try to use a button to create items (in the return() of my App.js)

{
  Categories.map(Category => ( //map categories output
    <form onSubmit={(e) => createItemInput(e, Category)}>
      <div className='item_input'>
        <input type="text" name="itemName" placeholder="New Item"/>
      </div>

      <button type="submit" id = "newItemButton">
        <svg width="30" height="30" viewBox="0 0 120 120" version="1.1" xmlns="http://www.w3.org/2000/svg">
          <line x1='0' y1='60' x2='120' y2='60' stroke='black' />
          <line x1='60' y1='0' x2='60' y2='120' stroke='black' />
        </svg>
      </button>
    </form>
  ))
}

and these are the relevant functions:

const initialFormState = { ItemName: "", ItemDescription: "", ItemCategory: {}}; //item form input


  const [Items, setItems] = useState([]); //items array
  const [formData, setFormData] = useState(initialFormState); //form data (form 1: items)


 async function createItem() { //create item function
    if (!formData.ItemName) return;

    await API.graphql({
      query: mutations.createItems,
      variables: {
        input: formData
      }
    })

function createItemInput(e, currentCategory) {
      e.preventDefault();
      var iname = e.target.itemName.value;
      setFormData({ ...formData, 'ItemName': iname, 'ItemCategory': currentCategory});
      createItem();
    }

when I click the button to create the item, the error I'm getting is this: "The variables input contains a field name 'ItemCategory' that is not defined for input object type 'CreateItemsInput' "

But the "ItemCategory" field is right there in the mutation, I don't know why it won't just create the item. If I try to create an item with DynamoDB directly into the database, I have no problem creating a map attribute called ItemCategory with an id and name. And I can console log the category map and get the object back but it won't be accepted when I try to create an item with it? It works if I take out all references to the ItemCategory and create an item with only an ItemName on button click, but I want the category to work as well.

EDIT So I tried to add this to the graphql:

input CreateItemsInput {
  ItemName: String!
  ItemDescription: String
  ItemCategory: Categories
}

but I get an update failed error when I try to push this. I tried it without the "ItemCategory: Categories" part and it did work. But I need the ItemCategory there. How do I get this to work? Any help would be appreciated.

Upvotes: 0

Views: 465

Answers (1)

MizzyV
MizzyV

Reputation: 11

I added

input CreateItemsInput {
  ItemName: String!
  ItemDescription: String
  ItemCategory: CategoriesInput
}

input CategoriesInput {
  id: ID!
  CategoryName: String!
  CategoryItems: [Items]
  createdAt: AWSDateTime
  updatedAt:AWSDateTime
}

to the graphql and the above code is working as intended.

Upvotes: 1

Related Questions