Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nested query with variable in Apollo GraphQL

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!

like image 219
eaton9000 Avatar asked Aug 21 '18 23:08

eaton9000


People also ask

How do you create a nested query in GraphQL?

When setting up a field whose value is a custom type, we have to define a function that tells GraphQL how to get that custom type. In our case, we want to tell GraphQL how to get the posts if we have the author. We do that by defining a new root property inside resolvers.

How do you use variables in GraphiQL?

The GraphiQL client allows you to create variables for use in your queries. To add a query variable, click the Query Variables pane and enter a JSON object that defines your variable. To use a variable in your query, prepend the $ character to your variable name and use it to replace the desired value.

How do you pass two arguments in GraphQL query?

Multiple arguments can be used together in the same query. For example, you can use the where argument to filter the results and then use the order_by argument to sort them.


1 Answers

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
    }
  } 
}
like image 97
eaton9000 Avatar answered Oct 23 '22 05:10

eaton9000