How to use Variables in Input Query and Inside the Shopify function

Solved

How to use Variables in Input Query and Inside the Shopify function

yedla_dinesh
Shopify Partner
11 0 1

I'm currently facing an issue while trying to utilize input query variables within the index.js file in my Shopify function. Despite reviewing the documentation https://shopify.dev/docs/apps/functions/input-output/variables-queries, I've been unable to find a solution.

 

Basically, I want to apply a discount on the products that belong to the collection I am passing.

Here's the input.graphql file

 

 

query GetCartContents($selectedCollectionIds: [ID!]) {
  cart {
    lines {
      quantity
      merchandise {
        __typename
        ... on ProductVariant {
          id
          product {
            id
            inAnyCollection(ids: $selectedCollectionIds)
          }
        }
      }
    }
  }
  discountNode {
    metafield(namespace: "product-discount", key: "function-config") {
      value
    }
  }
}

 

 


and here's my product-discount index.js file

 

 

 

(input) => {
    const configuration = JSON.parse(
        input?.discountNode?.metafield?.value ?? "[]"
    );
    const discounts = [];
    const selectedCollectionIds = {
        selectedCollectionIds: ["gid://shopify/Collection/451434709290"],
    };

    for (const line of input.cart.lines) {
        if (
            line.merchandise &&
            line.merchandise.id &&
            line.merchandise.product
        ) {
            const product = line.merchandise.product;

            // Issue: How to pass the selectedCollectionIds to inAnyCollection?
            const isInSelectedCollection = product.inAnyCollection;

            console.log(isInSelectedCollection, "isInSelectedCollection");       
        }
    }

    if (!discounts.length) {
        return EMPTY_DISCOUNT;
    }

    return {
        discounts,
        discountApplicationStrategy: DiscountApplicationStrategy.Maximum,
    };
};

 

 

 

My main challenge is understanding how to pass the values from selectedCollectionIds to the inAnyCollection function.

If anyone within the Shopify community has experience with this or can provide insights into how to properly utilize input query variables within the index.js file, I would greatly appreciate your guidance. Any tips, code snippets, or explanations would be incredibly helpful in resolving this issue.

Thank you all in advance for your assistance and support.

Shopify Expert
Helping thousands of @Shopify store owners to achieve sustainable growth & increase revenue 2-3x 
Accepted Solution (1)
phester17
Shopify Partner
22 1 10

This is an accepted solution.

I was also confused about this and just figured it out.

 

When building the discount form, the discount object metafield value needs to have a  property called "selectedCollectionIds" that stores the selected ids. For example:

 

const discount = {
    functionId,
    combinesWith: form.combinesWith,
    startsAt: form.startDate,
    endsAt: form.endDate,
    metafields: [
        {
            namespace: metafields.config.namespace,
            key: metafields.config.key,
            type: "json",
            value: JSON.stringify({
                quantity: parseInt(form.config.quantity),
                percentage: parseFloat(form.config.percentage),
                selectedCollectionIds: form.config.selectedCollectionIds || []
            })
        }
    ]
};

 
Next, in the shopify.function.extension.toml file add the metafield namespace and key for your app as an input variable. For example:

[input.variables]
namespace = "$app:product-discount"
key = "function-config"


Then the "$selectedCollectionIds" variable in the graphql file will pull from the selectedCollectionIds property in the discount metafield value. 

View solution in original post

Replies 3 (3)

Liam
Shopify Staff
2807 310 805

Hi Yedla_dinesh,

 

Based on the provided code snippets, it looks like you're trying to use the selectedCollectionIds variable inside the JavaScript function but this variable is defined in the GraphQL query context.

 

The inAnyCollection field in the GraphQL API is expecting an array of IDs passed as a variable (selectedCollectionIds in your case). But in your JavaScript function, it's being used as a property of product object and not as a function that you can pass arguments to.

 

To solve this issue, you should first ensure that your GraphQL query is correctly passing the selectedCollectionIds variable to the inAnyCollection field.

So, the query should look something like this:

query GetCartContents($selectedCollectionIds: [ID!]!) {
  cart {
    lines {
      quantity
      merchandise {
        __typename
        ... on ProductVariant {
          id
          product {
            id
            inAnyCollection(ids: $selectedCollectionIds)
          }
        }
      }
    }
  }
  discountNode {
    metafield(namespace: "product-discount", key: "function-config") {
      value
    }
  }
}

In your JavaScript function, the inAnyCollection field will be a boolean property of the product object (true if the product is in any of the selected collections, and false otherwise). You can then use this property to apply discounts to the appropriate products:

(input) => {
    const configuration = JSON.parse(
        input?.discountNode?.metafield?.value ?? "[]"
    );
    const discounts = [];

    for (const line of input.cart.lines) {
        if (
            line.merchandise &&
            line.merchandise.id &&
            line.merchandise.product &&
            line.merchandise.product.inAnyCollection // Use inAnyCollection field as a boolean property
        ) {
            // Apply discount
            // ...
        }
    }

    if (!discounts.length) {
        return EMPTY_DISCOUNT;
    }

    return {
        discounts,
        discountApplicationStrategy: DiscountApplicationStrategy.Maximum,
    };
};

Please note, the selectedCollectionIds variable should be passed to the GraphQL API when you're making the API call, not inside the JavaScript function. 

 

Hope this helps,

Liam | Developer Advocate @ Shopify 
 - Was my reply helpful? Click Like to let me know! 
 - Was your question answered? Mark it as an Accepted Solution
 - To learn more visit Shopify.dev or the Shopify Web Design and Development Blog

yedla_dinesh
Shopify Partner
11 0 1

Thanks for your reply, @Liam . I have tried to pass selectedCollectionIds as an array, but it's still not working.

Let's say I have an output like the following in metadata:

selectedCollectionIds: ["gid://shopify/Collection/123", "gid://shopify/Collection/321", "gid://shopify/Collection/987"]

Could you guide me on how to utilize this metadata in the inAnyCollection function to receive a true or false value in return?

Shopify Expert
Helping thousands of @Shopify store owners to achieve sustainable growth & increase revenue 2-3x 
phester17
Shopify Partner
22 1 10

This is an accepted solution.

I was also confused about this and just figured it out.

 

When building the discount form, the discount object metafield value needs to have a  property called "selectedCollectionIds" that stores the selected ids. For example:

 

const discount = {
    functionId,
    combinesWith: form.combinesWith,
    startsAt: form.startDate,
    endsAt: form.endDate,
    metafields: [
        {
            namespace: metafields.config.namespace,
            key: metafields.config.key,
            type: "json",
            value: JSON.stringify({
                quantity: parseInt(form.config.quantity),
                percentage: parseFloat(form.config.percentage),
                selectedCollectionIds: form.config.selectedCollectionIds || []
            })
        }
    ]
};

 
Next, in the shopify.function.extension.toml file add the metafield namespace and key for your app as an input variable. For example:

[input.variables]
namespace = "$app:product-discount"
key = "function-config"


Then the "$selectedCollectionIds" variable in the graphql file will pull from the selectedCollectionIds property in the discount metafield value.