Integer metafield is treated as string by Liquid

Matt_Stubbs
Shopify Partner
70 0 10

Hello,

I've got an integer metafield with a value of 12 on a product.

When I use it with a comparison operator:

{% if product.metafields.question_time.questions_count > 0 %}

I get an error: 'Liquid error: comparison of String with 0 failed'

Liquid seems to be treating the metafield as a string even though the API confirms the metafield is an integer.

According to the documentation integer metafields should be treated as such by Liquid:

You can also specify a metafield as either an integer or a piece of text (a “string”). That way, you’ll end up with the right type of data when you use the metafield in your Liquid.

 

Is this a known problem? Or am I missing something here?

Many thanks,

Matt

 

Developer of Back in Stock, the easiest way to increase sales on out of stock products. https://apps.shopify.com/back-in-stock
Replies 25 (25)

Chris_Saunders
Shopify Staff
591 0 53

I just want to confirm that you created your metafield with the value_type set to "integer".

 

Chris | 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 the Shopify Help Center or the Shopify Blog

Matt_Stubbs
Shopify Partner
70 0 10

Yes, I created it as an integer. I then checked by retrieving the metafield through the API and it reports the value_type as integer. The product id is 95821994 if you want to verify from your end?

 

Developer of Back in Stock, the easiest way to increase sales on out of stock products. https://apps.shopify.com/back-in-stock

HunkyBill
Shopify Expert
4845 60 547

I see the same problem. Integer metafields are nothing but strings to shop Liquid...

Custom Shopify Apps built just for you! hunkybill@gmail.com http://www.resistorsoftware.com

Matt_Stubbs
Shopify Partner
70 0 10

Thanks for the confirmation, Bill. Took an hour of thinking I was going mad before I finally decided it might be a bug!

In case anyone with the same problem comes across this post in future I'm using the plus filter to cast the string to an integer as a workaround:

{% assign my_integer_variable = product.metafields.question_time.questions_count | plus:0 %}

You can then use `my_integer_variable` as an actual integer.

Would be nice to have this fixed though, Chris 🙂

Developer of Back in Stock, the easiest way to increase sales on out of stock products. https://apps.shopify.com/back-in-stock

Jason
Shopify Expert
11190 225 2282

Would be nice to have integer support in general.

★ I jump on these forums in my free time to help and share some insights. Not looking to be hired, and not looking for work. http://freakdesign.com.au ★

Chris_Saunders
Shopify Staff
591 0 53

I've filed a ticket about this. I'm on the team that is responsible for liquid drops and all that fancy business in Shopify storefront. I can't make any promises about when it'll be shipped, but this article is in the ticket so when it ships I'll try my best to remember and provide an update about it.

Chris | 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 the Shopify Help Center or the Shopify Blog

Matt_Stubbs
Shopify Partner
70 0 10

That's great, thanks, Chris.

Developer of Back in Stock, the easiest way to increase sales on out of stock products. https://apps.shopify.com/back-in-stock

Chris_Saunders
Shopify Staff
591 0 53

Just to provide an update - We've gotten to the source and I've got a patch in review. It's reverse compatible with the current liquid implementation you are using, but you can just compare integers if that's the data type you know you'll be working with.

Chris | 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 the Shopify Help Center or the Shopify Blog

Michael_Klett
Visitor
3 0 0

I'm guessing this patch got released?  We had a bug in our integration that just got revealed by this.

Let me explain, Chris, and you can let me know if there are any workarounds:

We had a metafield that was being defined as an integer by mistake - it was really supposed to be a string.  It didn't get caught since it was still treated as a string when we read it, and all was working.  Then, starting today-ish, those strings started returning "0" instead of their original value.

The unfortunate part is that it appears that the stored data has been converted to an integer (I'm guessing you guys did a data migration to convert all of the integer fields to an integer in storage?)  If I change the metafield type to a string, I don't get my old value back - I still get back "0".

Am I correct about that last bit?  Or is there some way to recover our originally stored strings?  Its going to be very hard to reproduce this data - we've got thousands of these metafields spread around hundreds of different shops on our install base.

Thanks,

Michael

Chris_Saunders
Shopify Staff
591 0 53
The data should still be fine. This is a long shot but try updating the metafields to be the proper value type of string and see if you can recover your data.

Chris | 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 the Shopify Help Center or the Shopify Blog

Michael_Klett
Visitor
3 0 0

Chris, thanks for the reply.  You are correct - if I update the metafield to be type "string" then the data does come through with its original value.  (I was wrong earlier when I thought it didn't)

Thanks, Michael

Michael_Klett
Visitor
3 0 0

I wanted to share a small gotcha regarding this for others who may be experiencing the same issue:

Care must be taken if you are using the Shopify ruby gem, and you need to change the metafield value_type without changing the actual value.  If you, like me, erroneously stored a string value but set the value_type to integer, your data now (probably) reads out as "0" rather than your original string.  The data CAN be recovered by changing the value_type to string, but you must take care not to overwrite your data at the same time.  ActiveResource (the lib that underlies the Shopify ruby gem) sends by default ALL of the fields when performing an update - including your value field which now looks like a "0".

Don't do this:

metafield # => {"value" => 0, "value_type" => "integer"}
metafield.value_type = "string"
metafield.save
# You just overwrote "value" with "0"!

Instead I suggest:

metafield # => {"value" => 0, "value_type" => "integer"}

minimal_attributes = metafield.attributes.slice("id", "owner_id", "owner_resource")
minimal_attributes.merge!("value_type" => "string")

metafield.attributes = minimal_attributes
metafield.save
# You updated just value_type and left the value as it was.  If you had a string in there before, you now have access to it again

 

Chris_Saunders
Shopify Staff
591 0 53

Yeah, it's kind of one of my peeves with ActiveResource. It sends everything instead of just the data that changed 😞

Thanks for sharing!

Chris | 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 the Shopify Help Center or the Shopify Blog

Red_Hot_Toys
Excursionist
164 0 13

Can anyone help - we have many Metafields saved as integer type but which had decimals and we output them as e.g. {{ product-block.metafields.inventory.inches }}.  But we had data values in there that were decimals like 9.5. 

They are now showing as eg. "9".   How do we output the original data?  We are tld we need to convert integer to string.  How do we do that outside of the API?

+ Shopify - why do you do such things without telling people?

 

Chris_Saunders
Shopify Staff
591 0 53

You'll need to update your metafields such that they are stored as integers. So get all your metafields of interest and simply update their value_type.

PUT /admin/metafields/1234.json

{
  "metafield" : {
    "value_type": "string"
  }
}

This was brought to our attention and was actually showing that our API was broken since values were supposed to be integers but were being stored as strings. There was nothing preventing any value from being set as an integer, so you could create a metafield whose value is "abracadabra" with a value_type of integer and that would be "correct".

Chris | 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 the Shopify Help Center or the Shopify Blog

Chris_Saunders
Shopify Staff
591 0 53

I've written up a little migration guide / explanation of whats going on and how to resolve it. I'd like to thank Michael Klett for his notes about the Shopify API gem since I used them as part of the guide.

Thanks for all your feedback and apologies for any problems this might have caused.

Chris | 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 the Shopify Help Center or the Shopify Blog

Red_Hot_Toys
Excursionist
164 0 13

Eh? why can we just convert integer to string and get back the original data?

Chris_Saunders
Shopify Staff
591 0 53

The values are stored as strings because it's the "common denominator" of data-types. So we are just coercing the data to the expected data-type when we read it out of the database. So if it's an integer we coerce it into an int.

Chris | 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 the Shopify Help Center or the Shopify Blog

Red_Hot_Toys
Excursionist
164 0 13

Hi Chris - can you help explain 

so for example on our site  {{ product.metafields.inventory.inches }} output numbers like 9.5 but now outputs 9

What exactly to we write to output the 9.5 underlying data?

Chris_Saunders
Shopify Staff
591 0 53

You need to migrate your data over in the manner that Michael talked about. The data being stored is the same but because you set it to integer it's getting coerced from a string of 9.5 to 9

Chris | 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 the Shopify Help Center or the Shopify Blog

Jason
Shopify Expert
11190 225 2282

@Red Hot -- I've added a switch button to ShopifyFD so you can toggle the value_type as required.

★ I jump on these forums in my free time to help and share some insights. Not looking to be hired, and not looking for work. http://freakdesign.com.au ★

Red_Hot_Toys
Excursionist
164 0 13

You beauty !  It works - thanks for sorting our Shopifys mess, you should work for them,  At least we can now get the data one by one.  It would be nice if Shopify has offered to migrate the data for us, rather than tell us to deep dive into API/JSON solutions

Brandt_Milczew1
Tourist
4 0 1

Something with this update has broken my use of meta-fields. I have a meta field on product called size_chart it is set to type integer. I'm really using it as a boolean with 1 being "yes there is a sizing chart"

 

Here's how I display the button in my theme.

{% if product.metafields.attributes.size_chart == '1' %}
  {% assign file_name = product.id | append: '_sizingchart.png' %}
  <a href="{{ file_name | asset_url }}" class="action-button" onError="style.display='none';">
      Sizing Chart
  </a>
{% endif %}

The idea is that if the value is set to 1 then create a button that opens the appropriate sizing chart.

It was working last week and this week it is not. Any ideas?

Matt_Stubbs
Shopify Partner
70 0 10

Hi Brandt,

1 is an integer, but '1' is a string.

I would try changing this line:

{% if product.metafields.attributes.size_chart == '1' %}

to compare with an integer value (no quotes) like this:

{% if product.metafields.attributes.size_chart == 1 %}

 

Does that fix the issue?

 

Developer of Back in Stock, the easiest way to increase sales on out of stock products. https://apps.shopify.com/back-in-stock

Brandt_Milczew1
Tourist
4 0 1

Bingo! Thanks for pointing out something that I should have seen! haha.

I'll blame the bug in the API for allowing it to work in the first place. 😉 

Thanks for fixing it Shopify!