Strange behavior observed in the trailing comma in Shopify

I had a vanilla js script that initially appeared as follows:

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

My goal was to link similar products based on their titles. I achieved this by modifying the script like so:

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

The functionality worked correctly, but there were issues with the implementation that required me to create a JSON API in Shopify. The issue I encountered involved handling trailing commas when trying to replicate the above code block using Liquid in a JSON format. This resulted in unexpected token errors due to the presence of trailing commas.

I identified that the if statement within the Liquid code was causing the trailing comma problem, and I am currently struggling to find a solution. My Liquid code is structured as follows:

{% 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 resulting output exhibits correct linked products but lacks proper comma placement.

{
  "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"
              }, 
        ]
      }
    
  ]
}

While the linked products are accurately displayed, the formatting issue with commas remains unresolved.

Answer №1

When it comes to adding a comma based on a specific condition, the challenge lies in not knowing when that condition will be met for a related product. One approach is to utilize the capture tag to capture the raw string, ensuring a comma is appended whenever a related product is identified. This method guarantees an extra comma is always included at the end of the raw string, which can then be easily trimmed before using the string in your output. To achieve this, you can employ the remove_last filter as demonstrated below:

{
  "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 -%}
  ]
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Retrieve all elements within the iframe element

I have encountered a situation where I am using an iframe tag to load an epub file. However, I'm unsure of how to access all the elements within the iframe tag. jQuery(document).ready(function($) { var content = $('#epub_loader iframe&apo ...

Displaying live data from an XMLHttpRequest in a Vue component in real-time

I'm currently working on implementing lazy loading for a list of posts fetched from the WordPress REST API. My goal is to load additional news stories upon clicking an HTML element. However, I'm facing issues with accessing the original Vue inst ...

What is the best way to efficiently bulk insert a 600MB large JSON file into Elasticsearch?

My challenge is to add a 600MB Json file (which may grow in size) to Elasticsearch. However, I keep encountering the following error: Error: "toString()" failed I've tried using the stream-json npm package but it hasn't worked out for me. Is th ...

What is the origin of TrackballControls?

Seeking to enhance camera control within a threejs environment. After examining this specific demo, it appears that the functionality is largely achieved through the following lines of code: controls = new THREE.TrackballControls( camera ); controls.rota ...

convert json information into individual lines within a csv document

I have a CSV file as well as a JSON file with multiple lines structured like this: { "name":"John", "age": {"f": "1", "f2": "2"}, "city":"New York"} { "name" ...

Implementing functions to deactivate and activate features in Summernote editor

For a while now, I have been using the summernote editor and it has fulfilled most of my needs. However, I recently encountered an issue where I needed to disable it (not destroy it) after a user action. After several unsuccessful attempts, I realized that ...

Explore various locations and conceal different divs by clicking

Can someone help me figure out how to hide the placeholders when the focus changes in a form? Here is the code snippet that illustrates my problem. Your assistance is greatly appreciated, João var inputs = Array.prototype.slice.call(document.querySele ...

Customizing the background color of an option using HTML and CSS

I am currently developing an option form where each selection will appear in a different color as the user scrolls down. Once a selection is made, it should be saved and displayed with the chosen color. https://i.sstatic.net/gvdpt.png My goal is to save ...

The onchange function seems to be malfunctioning when attempted with AJAX

Help needed: I'm new to AJAX and facing an issue. I have implemented AJAX pagination to display data, which is working fine. But now I want to add a filter to the displayed data, however, the filter is not functioning correctly. <select name="prof ...

The output of jQuery('body').text() varies depending on the browser being used

Here is the setup of my HTML code: <html> <head> <title>Test</title> <script type="text/javascript" src="jQuery.js"></script> <script type="text/javascript"> function initialize() { var ...

React hook issue: useEffect not updating socket.io-client

Although I am attempting to receive updated values of react hooks inside the socket on function, unfortunately, it seems that the values are not being updated. Even if I edit the react hook values, the changes are not being reflected inside the socket. Her ...

Many mistakes encountered while trying to import web3 into app.js

Encountered 9 errors while trying to import web3 into App.js import React from "react"; import Web3 from "web3"; function App() { return ( <div className="App"> <h1>TEST APP</h1> </div> ...

Utilizing JSON parsing to integrate API with Android ListView

When trying to parse the JSON value into my ListView, I encountered an error in logcat stating a JSON parsing error. Instead of the result displaying in the ListView, the entire JSON response is showing in a toast message. Can someone please assist me in r ...

Differentiate the items within a list containing identical divs using JavaScript

Currently, I am expanding my knowledge in HTML, CSS, and JS by incorporating Angular and JQuery. In one of my projects, there is a div labeled "eventBoxes" where multiple divs known as "eventBox" can be added. I have created a template for the eventBox i ...

Different approach in Vuejs for selecting target/currentTarget in a list

I have my current configuration set up as depicted below: [{ name: "test", tags: ["aa","bb","v"] }, ...] <div class="item" v-for="item in sdList" :data-id="item.id"> <span @click="deleteTag(item, $event)" v-for="tag in item.tags ...

Eliminating unnecessary commas to properly format JSON in bulk operations

I am attempting to display the list of patches in JSON format like this: "patches" : { "1" : "KB123456", "2" : "KB123456", ... But, what I am actually getting is: "patches" : { "1" : "", "2" : "patch[2]", "3" : "patch[3]", ... This is the code that I a ...

Struggling to interpret JSON using JavaScript and Ajax

I have a PHP script that generates a .json file: <?php $data=array( "Name"=>"John", "Surname" => "Doe"); $jsontext = "["; foreach($data as $key => $value) { $jsontext .= "{objectValue: '".addslashes($key)."', textObject: &apo ...

Steps for positioning the date popup below the text field

My task in Angular 4 involves creating a date field that displays a date popup beneath it when clicked. See below for my code snippet: <div class="col-3"> <div class="form-group calenderForm calenderForm1"> <label for="templateName"& ...

Conceal the <p> tag if the content inside is either "0" or blank

I'm currently working on a basic calculator project and I've hit a roadblock. I need to hide certain elements based on conditions. The code snippet with explanations is provided below. function calculateArea() { var length = document.getElem ...

Having difficulty with Axios due to the URL containing a potent # symbol

When I pass a URL in axios, such as: https://jsonplaceholder.typicode.com/todos/#abc?pt=1 I only seem to receive the base URL in my network requests: https://jsonplaceholder.typicode.com/todos/ If anyone has insight on correctly passing URLs with #, yo ...