1

Sorry for the long post, but I tried to be as detailed as possible.

How can I edit my current model, schema, and resolver to be able to save/connect a related type (Vendor) to my created type (Item) via a web form?

I want to create an inventory item and select a vendor to be associated with that item.

I have a Prisma data model like so (I've other fields for simplicity because I have no trouble saving the other fields; it's just with other types where there is a relation)...

Items may or may not have a vendor associated with them. Vendors may or may not have a list of items currently associated with them.

type Item {
  id: ID! @id
  name: String!
  description: String!
  vendor: Vendor
}

type Vendor {
  id: ID! @id
  items: [Item!]
}

I have a graphql schema like this (compare to modified schema at the end of this question)...

type Mutation {
  createItem(
    name: String! 
    description: String! 
  ): Item!
}

My resolver:

async createItem(parent, args, ctx, info) {
  const item = await ctx.db.mutation.createItem(
    {
        data: {
            ...args,
        },
    }, info);

    return item;
}

My React component contains the following:

const CREATE_ITEM_MUTATION = gql`
  mutation CREATE_ITEM_MUTATION(
    $name: String!
    $description: String!
  ) {
    createItem(
      name: $name
      description: $description
    ) {
      id
      name
      description
      vendor {
        id
      }
    }
  }
`;
const ALL_VENDORS_QUERY = gql`
  query ALL_VENDORS_QUERY {
    vendors {
      id
    }
  }
`;

Later on down the web page in my HTML form, I have:

<Query query={ALL_VENDORS_QUERY}>
  {({ data, loading }) => (
    <select
      id="vendor"
      name="vendor"
      onChange={this.handleChange}
      value={this.state.vendor}
    >
      <option>Vendor</option>
        {data.vendors.map(vendor => (
          <option key={vendor.id} value={vendor.id}>{vendor.name}</option>
        ))}
    </select>
  )}
</Query>

I just don't know how to connect the vendor to the item through a form submission. I can get it working if I hard code the vendor id in my resolver like so:

async createItem(parent, args, ctx, info) {
  const item = await ctx.db.mutation.createItem(
    {
        data: {
            vendor: {
              connect: { id: "ck7zmwfoxg4b70934wx8kgwkx" } // <-- need to dynamically populate this based on user input from the form
            },
            ...args,
        },
    }, info);

    return item;
}

...but that obviously is not what I want.

To me, it makes the most sense to modify my schema like so:

createItem(
  name: String!
  description: String!
  vendor: Vendor <--- added
): Item!

But when I do that I get this:

Error: The type of Mutation.createItem(vendor:) must be Input Type but got: Vendor.

How can I edit my current model, schema, and resolver to be able to save/connect a vendor ID that is selected on the form?

James Trenda
  • 859
  • 7
  • 7

1 Answers1

1

The answer to my problem was found here: How to fix 'Variable "$_v0_data" got invalid value' caused from data types relation - Mutation Resolver

I was spreading the args (...args) while also passing the vendor argument.

Here is my updated mutation:

createItem(
    name: String!
    description: String!
    vendorId: ID
    ): Item!

and its resolver:

async createItem(parent, {name, description, vendorId}, ctx, info) {
  const item = await ctx.db.mutation.createItem(
    {
        data: {
            vendor: {
              connect: { id: vendorId }
            },
            name,
            description,
        },
    }, info);

    return item;
}

Boom!

James Trenda
  • 859
  • 7
  • 7