Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

list.product_reference.size #1589

Open
Tracked by #1743
chucklin72 opened this issue Jul 3, 2022 · 26 comments
Open
Tracked by #1743

list.product_reference.size #1589

chucklin72 opened this issue Jul 3, 2022 · 26 comments

Comments

@chucklin72
Copy link

I have a custom metafield of a product list.
When I display the list {{ product.metafields.custom.mylist }}
["gid://shopify/Product/7668926775542","gid://shopify/Product/7491343778038"]

but
{{ product.metafields.custom.mylist.size }}
shows nothing

is list !== array?

@LeafedFox
Copy link

We are having the same issue. Plus, giving the array to the Size filter always returns 0, whether the size is 0 or not

@osea-malibu
Copy link

Having the same problem, can iterate over the array but size returns nothing.

If the product reference list metafield has never been used, i can check if it's nil: {% if product.metafields.custom.mylist == nil %}
But if the metafield has been used, but the data was removed, it isn't nil. The value console logs as []. But {% if product.metafields.custom.mylist.value.size > 0 %} doesn't work. This makes it impossible to check if there is data entered in the metafield.

I've been unable to find a workaround for this.

@chucklin72
Copy link
Author

Is it that the "list" is only the storage of the data but the metafield is only storing string? maybe it only works with JSON.parse( product.metafields.custom.mylist)?

@mjolliffe
Copy link

This worked for me:

{%- assign product_list = product.metafields.custom.mylist | split: ',' | uniq -%}
{{ product_list.size }}

@t3pfaffe
Copy link

t3pfaffe commented Nov 15, 2022

Still running into this issue as well but with collection lists (metafield type list.collection_reference). This issue was confirmed by Shopify support staff. Hoping this gets some attention from the maintainers soon.

@bendhu
Copy link

bendhu commented Jan 15, 2023

upon till today this is still an issue, i.e. metafields of type list is not an array either has a size method.
Following works for now, i.e. manually converting it into an array of strings, then use its size.

{% assign productIngredients = product.metafields.custom.ingredient_details.value %}
{% assign productIngredientsArray = product.metafields.custom.ingredient_details | split: ',' %}  // might want the uniq filter too
{% assign productIngredientsTotal = productIngredientsArray.size %}

@annatwp
Copy link

annatwp commented Feb 2, 2023

Using .count instead of .size solves this issue for me.

@alvinkonda
Copy link

Using .count instead of .size solves this issue for me.

Interesting, It seems ProductListDrop is not a type of array.

@pablogiralt
Copy link

@annatwp solution worked for me

@MaxDesignFR
Copy link

This trick might work to get the size, but this prevents to access an object such as a product reference. I described the issue here: #1643 (comment) I really wonder why this is not fixed yet, very annoying that we can have list but can't navigate them with liquid array filters.

@masserra
Copy link

masserra commented Jun 5, 2023

Same here! Omg I'm going crazy with this issue.

Size isn't working either as a filter or using [dot]notation. It acts as if it doesn't have any item. Can't use conditional logic, can't loop over it, it's just like it's not an array...

But on the other hand when it gets JSON stringified it shows as an array on the console.

Here's some of the debugging I did:

Screenshot 2023-06-05 at 12 15 28 Screenshot 2023-06-05 at 12 09 35 Screenshot 2023-06-05 at 12 10 26

Hopefully this gets solved fast!

@cinghaman
Copy link

@masserra use .value so artists.size.value

@masserra
Copy link

masserra commented Jun 5, 2023

@masserra use .value so artists.size.value

I had tried {{ artists.value | size }} before, but it didn't work either.

Don't understand the why of using size.value, although I just tried it ({% if artists.size.value > 1 %}) and it didn't work either. Also this would not solve the for loop as it needs to be able to read the array as an array and until that happens size or anything else won't work.

@masserra
Copy link

masserra commented Jun 5, 2023

This worked for me:

{%- assign product_list = product.metafields.custom.mylist | split: ',' | uniq -%} {{ product_list.size }}

upon till today this is still an issue, i.e. metafields of type list is not an array either has a size method. Following works for now, i.e. manually converting it into an array of strings, then use its size.

{% assign productIngredients = product.metafields.custom.ingredient_details.value %}
{% assign productIngredientsArray = product.metafields.custom.ingredient_details | split: ',' %}  // might want the uniq filter too
{% assign productIngredientsTotal = productIngredientsArray.size %}

This is the only thing that worked for me to be able to use size..

BUT... then all I get is an array of metaobject GID reference strings ("gid://shopify/Metaobject/2167308566") which I can't find a way to access!

So... even though this was obviously a hack, this is definitely not the solution.

@masserra
Copy link

masserra commented Jun 7, 2023

Solution:

OK!! Finally found the cleanest hack to make the array behave like an actual array, a double reverse filter:
{% assign metaobjects = metafields.namespace.key.value | reverse | reverse %}

To come back to my real world example would look like:
{% assign artists = metafields.custom.artists.value | reverse | reverse %}

Key points that need to be reviewed:

  • The use of value is completely unintuitive. When logging the JSON stringified object/array there's nothing there to suggest the use of value. On top of that it's poorly documented if not completely undocumented.
  • Using value on its own doesn't even take you anywhere. The returned array won't work with the Shopify liquid standards such as size filter or for loops. You won't get an array of actual type array until we apply hacks such as the double reverse filter.
  • Due to the very unintuitive nature of value in conjunction with the array not behaving as expected we find ourselves completely lost throwing value everywhere until we realize it's a liquid bug.

@masserra
Copy link

masserra commented Jun 7, 2023

Note to the Shopify Liquid Team:

It's almost been 1 year since this issue has been opened, everywhere I look I see people struggling not only with the use of value but also with the fact that "list !== array" as @chucklin72 suggested. It's very confusing and it's clearly a liquid bug since double reverse filter finally turns the list into the expected array type.

The longer this goes on unsolved the more codebases might end up having a breaking change once you finally tackle the issue..

@MaxDesignFR
Copy link

MaxDesignFR commented Jun 7, 2023

I can't believe your solution is actually working!! Great finding @masserra You nailed it.

So something like this is now possible:

{%  assign my_product = product.metafields.custom.product_list.value | reverse | reverse %}
Product title: {{ my_product[1].title }}

A standard for loop works normally as well, but in some situations it is not a practical way to code:

{% for value in product.metafields.custom.product_list.value %}
    Product title: {{ value.title }}
{% endfor %}

I can't agree more with you with the issues you highlighted. Shopify simply ignores us here, I don't mean to be rude or offensive, but why did they not address this at least once, it is puzzling...

As for the metafields value, I belive this is the doc for liquid. I must say this is quite a gymnastic for the mind (especially metaobjects), not always easy to get it right the first time, but I suppose they've had a good reason to do it, and the changes they did to metafields are overall very good.

Now, I wonder if this "trick" is a good idea for production. Could it not backfire? As long as there is no breaking change introduced (which is something I've never seen Shopify do yet), I don't mind using this trick, this can make code simpler and cleaner.

@masserra
Copy link

masserra commented Jun 8, 2023

@MaxDesignFR 🙌 🙌 Thank you for that liquid doc, it completely escaped me. Although, what I also mean by "unintuitive" is that JSON stringifying the object doesn't expose the correct tree structure, it suggests that the list can be accessed straight away and that no other attribute (value) needs to be used to access the list 1 more step down the tree.

I spoke to a Shopify admin on discord and they said it's all about priorities as they have many other higher important issues to tackle, which I understand actually, they've indeed been pushing quite a lot of new exciting features lately 🫶

In regards to being production ready I don't see why it might not be. I'll choose this one over any other solution (for now) as this one at least is a clean & explicit hack that feels familiar to other devs and doesn't go around the problem too much, a simple comment and every dev will be in sync. Plus it enables us to use only Shopify's documented liquid standards and no undocumented ones such as .count.

@AJayHubs
Copy link

AJayHubs commented Jul 6, 2023

If size is 0 then I try count. Seems to be working for me.

@iconjenchua
Copy link

We have a metaobject that has a field that accepts products (list) and this is how I solved the counting issue:

assign gift_count = promo.product | split: ',' | size

@Czx00000 Czx00000 mentioned this issue Sep 12, 2023
@yotamcuralife
Copy link

{{ metafields.custom.array.value.count }} worked for me, God knows why.

@joeybab3
Copy link

joeybab3 commented May 6, 2024

{{ metafields.custom.array.value.count }} worked for me, God knows why.

I can confirm that .count worked for me where .size did not... Really annoying that they don't let you json print objects or really debug in anyway to find this out on our own.

@joshistoast
Copy link

This issue is now 2 years old, and while @masserra's hack works... I'd much rather not have to keep relying on workarounds for liquid's incompetencies.

@rcasimmons
Copy link

This issue is now 2 years old, and while @masserra's hack works... I'd much rather not have to keep relying on workarounds for liquid's incompetencies.

I've been struggling with this for going on the time that file 'list' metafields have been a thing to allow clients to upload multiple images and I've finally found this after 2/3 years.

@MaxDesignFR
Copy link

I've been struggling with this for going on the time that file 'list' metafields have been a thing to allow clients to upload multiple images and I've finally found this after 2/3 years.

Ouch, that must have stung! It is a handy workaround. Definitely don’t miss that issue, it's been around for 11 years, but I'm sure they're all over it (I swear, I’m not delusional). If it ever gets resolved, it may change your liquid game and your life to some extent. Serious liquid fun right there.

@andrewchen5678
Copy link

Still an issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests