Rendering lists of 1 with hogan (using Shopify named tags)

I’ve been using named tags on the product model to add metadata to product page & in search results. This has been great so far, particularly for lists (arrays) of metadata that need to be associated with a particular product.

However, one issue I’ve run into is that Hogan doesn’t seem to render lists of 1.

I’ve been using this code to render named tags in the algolia_instant_search_product.hogan.liquid file:

<div class="col-xs-2 c-ais-species_reactivity">
  [[# named_tags.speciesReactivity ]]
    <span class="reactivity_item" data-application="[[ . ]]"></span>
  [[/ named_tags.speciesReactivity ]
</div>

(Ignore the fact that [[ . ]] is in the data-attribute field :slight_smile: that’s just one little hack I had to do to get the list to display the right way on the product page and in the search results.)

This code is working great for products that have more than 1 speciesReactivity named tag, however, if it only has 1 named tag, it doesn’t pull the value. You can see this in the column “Species Reactivity” on this page (password: xenopus).

The same issue is happening in the “Application” column on that page as well.

Also, I tested changing my code to this:

<div class="col-xs-2 c-ais-species_reactivity">
  [[# named_tags.speciesReactivity ]]
    <span class="reactivity_item" data-application="[[ named_tags.speciesReactivity ]]"></span>
  [[/ named_tags.speciesReactivity ]
</div>

Which resulted in the opposite error, products with exactly 1 speciesReactivity named_tag displayed, but those with more than 1 did not.

Any insights? I have thought about putting both [[ . ]] and [[ speciesReactivity ]] inside the block, but it duplicates. Is there a way to check if the list has 1 item? Or use some if/else statements?

Appreciate the insight!

Hi,

Thanks for reaching out. Why don’t you try to use hogan helpers ?

The idea would be to define the helpers in assets/algolia_helper.js in which you would pass the speciesReacrivity variable as argument. I am not sure to understand why it does not work, but with that, you could print the variable inside the function to make some debug. For example, checking the size or simply print the array. If the size and variable are correct even in the case you described you could use the helpers function to iterate other the array and return the HTML.

Let me know if you have other questions!

Alex’s suggestion will probably be the right one.

For an explanation as to why this is the behavior you’re experiencing, you should compare two records:

  • one with only one speciesReactivity
  • one with multiple speciesReactivity

The first one should not have an array, but simply a string.
Indeed, named_tags will be converted to an array when we have multiple of them. But by default, it simply takes the value and assigns it to the attribute you’ve chosen.

What you could also do is, inside the transformData of the hits widget, convert this attribute to an array when it isn’t one:

        transformData: {
          item: function (product) {
            product._distinct = instant.distinct;
            product.can_order = (
              product.inventory_management !== 'shopify' ||
              product.inventory_policy === 'continue' ||
              product.inventory_quantity > 0
            );
            product.translations = algolia.translations;
            product.queryID = instant.search.helper.lastResults._rawResults[0].queryID;
            product.productPosition = product.__hitIndex + 1;
            if (typeof product.named_tags.speciesReactivity === 'string') {
              product.named_tags.speciesReactivity = [product.named_tags.speciesReactivity];
            }
            return product;
          },

@Jerska

Thanks for your wisdom once again! One modification to your code was all it took, I needed to add typeof() around product.named_tags.speciesReactivity in the if statement. This was the final result that worked.

if (typeof(product.named_tags.speciesReactivity) === 'string') {
  product.named_tags.speciesReactivity = [product.named_tags.speciesReactivity];
}
return product; 

Thanks!!

1 Like

Indeed, nice catch, I forgot the keyword, I’ve just edited my message! Glad it worked!