curious
curious

Reputation: 831

How to pass nested variables to the GraphQL query in Apollo?

Trying to pass nested variables to the GraphQL query but my server gets only top-level variables (shopId), everything else is null.

I tried:

#1

const CALCULATE_PACKAGE_PRICE = gql`
  query CalculatePackagePrice(
    $shopId: String!
    $address1: String
    $zip: String
    $city: String
    $countryCode: String
    ) {
    calculatePackagePrice(
      where: {
        shopId: $shopId
        destination: {
          address1: $address1
          zip: $zip
          city: $city
          countryCode: $countryCode
        }
      }
    ) {
      name
      price
      userErrors {
        field
        message
      }
    }
  }
`

const [calculatePackagePrice, { loading, data }] = useLazyQuery(
  CALCULATE_PACKAGE_PRICE,
  {
    variables: {
      shopId: shopId,
      destination: {
        address1: "Example 123",
        zip: "123",
        city: "Test",
        countryCode: "US",
      },
    },
  }
)

And #2:

export function CALCULATE_PACKAGE_PRICE({ shopId, destination }) {
  return gql`
    query CalculatePackagePrice {
        calculatePackagePrice(
          where: {
            shopId: "${shopId}"
            destination: {
              address1: "${destination.address1}"
              zip: "${destination.zip}
              city: "${destination.city}"
              countryCode: "${destination.countryCode}"
            }
          }
        ) {
          name
          price
          userErrors {
            field
            message
          }
        }
      }
  `
}


const [calculatePackagePrice, { loading, data }] = useLazyQuery(
  CALCULATE_PACKAGE_PRICE({
    shopId: shopId,
    destination: {
      address1: "Example 123",
      zip: "123",
      city: "Test",
      countryCode: "US",
    },
  })
)

It works just fine when I hardcoded variables content to the queries. What I'm doing wrong?

Upvotes: 3

Views: 5064

Answers (1)

Nicholas Harder
Nicholas Harder

Reputation: 1558

Here is a helpful snippet from graphql docs,

All declared variables must be either scalars, enums, or input object types. So if you want to pass a complex object into a field, you need to know what input type that matches on the server.

You're correctly passing in the variables as strings, but then trying (perhaps successfully, but I've never seen the syntax before) to create the object in the gql template string. Instead, create an input type for destination and where.

input WhereInput {
  shopId: String!
  destination: DestinationInput!
}

input DestinationInput {
  address1: String!
  zip: String!
  city: String!
  countryCode: String!
}

then change the query on the client (and update the server definition),

const CALCULATE_PACKAGE_PRICE = gql`
  query CalculatePackagePrice($where: WhereInput!) {
    calculatePackagePrice(where: $where) {
      name
      price
      userErrors {
        field
        message
      }
    }
  }
`

then pass the variables like,

const [calculatePackagePrice, { loading, data }] = useLazyQuery(
  CALCULATE_PACKAGE_PRICE,
  {
    variables: {
      where: {
        shopId,
        destination: {
          address1: "Example 123",
          zip: "123",
          city: "Test",
          countryCode: "US",
        },
      },
    }
  }
)

Upvotes: 6

Related Questions