6
votes

I am using Apollo server, trying to construct a nested query for an e-commerce application. I am querying an rest api to retrieve items in a shopping basket.

However the response of this request does not contain all the product information we need. So I am trying to nest an additional query, using one of the returned parameters as a variable in to get the additional product information required.

I have seen nested query examples and as far as I understand (I'm pretty new to GraphQL and Apollo in particular) this is one of the great things about GraphQL. But I haven't seen any examples where a nested query depends on the returned value from the parent query.

//typeDefs
const typeDefs = gql`
    type Product {
        id: ID
        name: String
        sku: String
        length: Float
    }
    type CartItem {
        id: ID
        product_id: ID
        quantity: Int
        product(product_id: ID!): Product
    }
    type Query {
        getProduct(id: ID!): Product
        getCartItems(id: ID!): [CartItem]
    }
`;
// resolvers
const processResponse = (resolved) => {
    try {
        const { data } = resolved;
        return data;
    } catch (error) {
        return error;
    }
};
const resolvers = {
    Query: {
        getProduct: async (parent, { id }, { ctx }) => {
            return processResponse(await ctx.get(`products/${id}`));
        },
        getCartItems: async (parent, { id }, { ctx }) => {
            return processResponse(await ctx.get(`carts/${id}/items`))
        }
    },
    CartItem: {
        product: async (parent, { product_id }, { ctx }) => {
            return processRequest(await ctx.get(`products/${product_id}`));
        }
    }
};

// and query in the playground
query {
  getCartItems(id:"1234b11") {
    id
    product_id
    quantity
    product(product_id: $product_id) {
      id
      name
      description
    }
  } 
}

And the error I get is Variable \"$product_id\" is not defined." When I hardcode product_id with an actual product_id I get the sort of response I want, but of course this isn't dynamic. I have tried passing variables to the query like query ($product_id: ID) but I get an error "Variable \"$product_id\" of type \"ID\" used in position expecting type \"String!\".",.

Any help appreciated!

1

1 Answers

5
votes

Solved this using the parent argument and not passing any variables to the child query.

//typeDefs
type CartItem {
    id: ID
    product_id: ID
    quantity: Int
    product: Product
}
//resolver
getCartItems: async (parent, { id }, { ctx }) => {
    return processResponse(await ctx.get(`carts/${id}/items`))
        },
CartItem: {
    product: async (parent, args, { ctx }) => {
    const productId = parent.product_id;
    if (productId) {
      const { data } = processResponse(await ctx.get(`products/${productId}`));
      return data
    }
}
//query
query {
  getCartItems(id:"1234b11") {
    id
    product_id
    quantity
    product {
      id
      name
      description
    }
  } 
}