I've a list of product handles stored in the main products metafield that I'm fetching in the following way:
{% assign firstComponentHandles = product.variants.first.metafields.custom.component_handles %}
const handlesData = {{ firstComponentHandles }};
console.log({handlesData});
Response:
{
"handlesData": [
"burger",
"carbonated-beverage"
]
}
Now I've taken multiple approach to fetch the products data using the handles. I've used the all_products liquid obj for fetching the data using the handles:
Using js:
<script>
{% assign firstComponentHandles = product.variants.first.metafields.custom.component_handles %}
const handlesData = {{ firstComponentHandles }};
console.log({handlesData});
const componentsData = [];
handlesData.forEach((componentHandle, index) => {
componentsData.push({ componentHandle: {{ all_products.componentHandle | json }} });
componentsData.push({ componentHandle: {{ all_products[componentHandle] }} });
});
console.log("Components Data:", componentsData);
</script>
Response:
Uncaught ReferenceError: EmptyDrop is not defined
Inspection on sources:
handlesData.forEach((componentHandle, index) => {
componentsData.push({ componentHandle: {"error":"json not allowed for this object"} });
componentsData.push({ componentHandle: EmptyDrop });
});
Using Liquid:
<script>
const componentsDataNew = [];
const componentsDataNew2 = [];
{% for handle in firstComponentHandles %}
componentsDataNew.push({handle: {{ all_products.handle | json }}})
componentsDataNew2.push({handle: {{ all_products[handle] | json }} });
{% endfor %}
console.log("Components Data Array New: ", componentsDataNew);
console.log("Components Data Array New 2: ", componentsDataNew2);
</script>
Response:
Components Data Array New: []
Components Data Array New 2: []
Passing static handle:
<script>
const dataUsingStatichandle = [];
dataUsingStatichandle.push({ burger: {{ all_products.burger }} });
dataUsingStatichandle.push({ burger2: {{ all_products["burger"] }} });
</script>
Response:
[
{ "burger": { "id": 8654927343434, "title": "Burger", ...moreData } },
{ "burger2": { "id": 8654905131564, "title": "Burger", ...moreData } }
]
So, I couldn't fetch the data using either Js or Liquid dynamically but I could fetch them passing the handle statically.
What am I doing wrong? I feel like this should be a syntax related issue.
I figured it out. The main problem was with the data format and it was a hectic process. It took me quite some time to figure out what was wrong.
1st problem that I found was that the liquid loop wasn't working with the data I was passing. I was getting the handles data as an array:
[
"burger",
"carbonated-beverage"
]
So then I assigned it to a Liquid variable and then I removed the '['
and then removed the ']'
. After removing the parenthesis I removed the '"'
double quotes. Then I split the result using ','
and then the handles were ready to use in a liquid loop.
The liquid code:
<script>
{% assign firstComponentHandles = product.variants.first.metafields.custom.component_handles %}
{{ firstComponentHandles }}
// Output: ["burger","carbonated-beverage"]
{% assign temp1 = firstComponentHandles | remove: '[' %}
temp1: {{ temp1 }}
// Output: temp1: "burger","carbonated-beverage"]
{% assign temp2 = temp1 | remove: ']' %}
temp2: {{ temp2 }}
// Output: temp2: "burger","carbonated-beverage"
{% assign temp3 = temp2 | remove: '"' %}
temp3: {{ temp3 }}
// Output: temp3: burger,carbonated-beverage
{% assign formattedHandles = temp3 | split: ',' %}
{{ formattedHandles }}
// Output: burgercarbonated-beverage
const productsWithVariantsQty = {};
{% for handle in formattedHandles %}
{% assign productFromHandle = all_products[handle] %}
// Initialize the key for each product handle and set it as an empty array
productsWithVariantsQty["{{ handle }}"] = [];
{% for variant in productFromHandle.variants %}
productsWithVariantsQty["{{ handle }}"].push({
variantInventoryQuantity: {{ variant.inventory_quantity }},
variantInventoryPolicy: "{{ variant.inventory_policy }}"
});
{% endfor %}
{% endfor %}
console.log("Products with Variants:", productsWithVariantsQty);
</script>