Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I create a mutation on a nested object with GraphQL?

I'm trying to create a graphql mutation to update an object field with an array of other objects. Here is my schema:

    type Guide {
      _id: ID!
      first_name: String!
      last_name: String
      email: String!
      phone: String!
      creator: User!
    }

    input GuideInput {
      _id: ID!
      first_name: String!
      last_name: String
      email: String!
      phone: String!
    }

    type Trip {
      _id: ID!
      name: String!
      description: String
      location: String
      start_date: String
      start_time: String
      duration: Int
      creator: User!
      guides: [Guide!]
      guests: [Guest!]
    }

    input TripInput {
      name: String
      description: String
      location: String
      start_date: String
      start_time: String
      duration: Int
      guides: [GuideInput]
    }

    type RootQuery {
      trips: [Trip!]
      guides: [Guide!]
    }

    type RootMutation {
      updateTrip(tripId: ID!, tripInput: TripInput): Trip
      deleteTrip(tripId: ID!): Trip
      createGuide(guideInput: GuideInput): Guide
      deleteGuide(guideId: ID!): Guide
    }

    schema {
      query: RootQuery
      mutation: RootMutation
    }

And my query looks like this:

const requestBody = {
      query: `
        mutation {
          updateTrip(
            tripId: "${tripId}",
            tripInput: {
              guides: ${guides}
            }
          ) {
            guides {
              first_name
              last_name
            }
          }
        }
      `
    }

The error I'm getting when I execute this request is:

Expected type GuideInput, found object.
Expected type GuideInput, found Object.

I am passing an array of objects into the mutation that is the same shape as the GuideInput object so I'm stumped. Thank you in advance!

like image 696
wileybaba Avatar asked Oct 16 '22 05:10

wileybaba


1 Answers

You cannot pass your inputs into your query this way. When you use template literals with placeholders, the result of the expression inside the placeholder (${guides}) is treated like a string. If guides is an Object (which it is, if it is an Array), it has toString() called on it, which results in the string [object Object]. You end up with a string that looks like:

tripInput: {
  guides: [object Object]
}

The correct way to substitute values inside your query is to use variables and avoid using placeholders altogether. Your requestBody would then look something like this:

const requestBody = {
  query: `
    mutation SomeMutationName($tripId: ID!, $guides: [GuideInput]) {
     updateTrip(
        tripId: $tripId
        tripInput: {
          guides: $guides
        }
      ) {
        guides {
          first_name
          last_name
        }
      }
    }
  `,
  variables: {
    tripId,
    guides,
  },
}

See the official tutorial and the spec for more details about how to use variables.

like image 177
Daniel Rearden Avatar answered Oct 21 '22 01:10

Daniel Rearden