Home > Blockchain >  Shopify trailing comma behaving strange
Shopify trailing comma behaving strange

Time:07-18

I had some vanilla js that looked like this

const products = [
    {
        id: 1,
        title: 't-shirt'
    },
    {
        id: 2,
        title: 't-shirt'
    },
    {
        id: 3,
        title: 'jeans'
    }
  ]

And I wanted to have these products linked if they had the same title. So I did it like this:

products.forEach(product => {
    product.linked_products = 
      products
        .filter(linked_product => linked_product.id !== product.id && linked_product.title === product.title)
  })

This worked the way it was supposed to. But the implementation was wrong and I had to create a small json api in shopify. I tried to achieve the above code block in just liquid in a json format and the if statement is causing the output to sometimes have and sometimes not have a trailing comma which breaks. When I fetch the endpoint I get an error about unexpected tokens because there are trailing commas.

I isolated this down to the if statement causes the trailing comma to not work and I am struggling how to fix this. my code looks like this

{% layout none %}

{
  "title": {{ collection.title | json }},
  "description": {{ collection.description | json }},
  "products": [
    {% for product in collection.products %}
      {
        "title": {{ product.title | json }},
        "linked_products": [
          {% for linked_product in collection.products %}
            {% if linked_product.id != product.id and linked_product.title == product.title %}
              {
                "title": {{ linked_product.title | json }},
                "handle": {{ linked_product.handle | json }}
              }{% unless forloop.last %},{% endunless %}
            {% endif %}
          {% endfor %}
        ]
      }{% unless forloop.last %},{% endunless%}
    {% endfor%}
  ]
}

The output I get is looking like this

{
  "title": "Leggings",
  "description": "",
  "products": [
      {
        "title": "High waisted leggings",
        "linked_products": [
              {
                "title": "High waisted leggings",
                "handle": "high-waisted-leggings-1"
              },
            
              {
                "title": "High waisted leggings",
                "handle": "high-waisted-leggings"
              }
        ]
      },
    
      {
        "title": "Test",
        "linked_products": [  
              {
                "title": "Test",
                "handle": "high-waisted-leggings-3"
              },
        ]
      },
      {
        "title": "Test",
        "linked_products": [
              {
                "title": "Test",
                "handle": "testb"
              },
        ]
      },
    
      {
        "title": "High waisted leggings",
        "linked_products": [
              {
                "title": "High waisted leggings",
                "handle": "high-waisted-leggings-2"
              },
            
              {
                "title": "High waisted leggings",
                "handle": "high-waisted-leggings"
              }
        ]
      },
    
      {
        "title": "High waisted leggings",
        "linked_products": [
              {
                "title": "High waisted leggings",
                "handle": "high-waisted-leggings-2"
              },
            
              {
                "title": "High waisted leggings",
                "handle": "high-waisted-leggings-1"
              }, 
        ]
      }
    
  ]
}

The linked products is indeed right, the comma just isn't working

CodePudding user response:

The problem with your condition to add comma is that you never know when the next time the if condition will be true for the related product. So, I have used the capture tag to capture the raw string, where a comma is added at the end anytime a related product is found. This condition will always add an additional comma at the end in raw string. Then, you can just remove the last comma before using this raw string in output. The following code using remove_last should work fine for your scenario.

{
  "title": {{ collection.title | json }},
  "description": {{ collection.description | json }},
  "products": [
    {%- for product in collection.products -%}
        {% capture linked_products_markup %}
            {%- for linked_product in collection.products -%}
                {%- if linked_product.id != product.id and linked_product.title == product.title -%}
                  {
                    "title": {{ linked_product.title | json }},
                    "handle": {{ linked_product.handle | json }}
                  },
                {%- endif -%}
            {%- endfor -%}
        {% endcapture %}
    
      {
        "title": {{ product.title | json }},
        "linked_products": [{{ linked_products_markup | remove_last: ','}}]
      }{% unless forloop.last %},{% endunless%}
    {%- endfor -%}
  ]
}
  • Related