Home > OS >  Handlebars - split string and iterate within {{each}}
Handlebars - split string and iterate within {{each}}

Time:07-06

Basically I am rendering a JSON file into a HTML template with Handlebars and all works fine except for one value where I get returned a string with comma separated values.

JSON file:

[
{
        "venue_state": "Everywhere",
        "venue_country": "United States",
        "venue_lat": "34.2347",
        "venue_lng": "-77.9482",
        "rating_score": "4",
        "created_at": "2022-07-01 17:13:16",
        "flavor_profiles": "malty,biscuity,grainy,clove,banana"
},
{
....
}
]

HTML

<script src="https://code.jquery.com/jquery-3.6.0.slim.min.js" integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI=" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/handlebars@latest/dist/handlebars.js"></script>
<script src="script.js"></script>

 <!--handlebars template-->
    <script id="checkin-template" type="text/x-handlebars-template">
    {{#each this}}
    <div >
       <h1>{{venue_country}}<h2>
       <p>{{venue_state}}</p>
        <div >
            <h1>{{rating_score}}</h1>
        </div>
         <ul >
                <li><a href="#" >{{flavor_profiles}}</a></li>
         </ul>
    </div>
    {{/each}}
    </script>
<div ></div>
          

script.js

$(document).ready(function () {

    var request = new XMLHttpRequest();
    request.open("GET", "testdata.json", false);
    request.send(null);
    var data = JSON.parse(request.responseText);
    //console.log(data);
    
    //compile template and fill with data
    var source = $("#checkin-template").html();
    var template = Handlebars.compile(source);
    $('.output').append(template(data));

});

This works except for {{flavor_profiles}}. What I want to get rendered is this

         <ul >
                <li><a href="#" >malty</a></li>
                <li><a href="#" >biscuity</a></li>
                <li><a href="#" >grainy</a></li>
                <li><a href="#" >clove</a></li>
                <li><a href="#" >banana</a></li>
         </ul>

What I actually get is

         <ul >
                <li><a href="#" >malty,biscuity,grainy,clove,banana</a></li>
         </ul>

and I guess it is because I get returned a string of comma separated values instead of an array?

I tried something like this

    <script id="checkin-template" type="text/x-handlebars-template">
    {{#each this}}
    <div >
       <h1>{{venue_country}}<h2>
       <p>{{venue_state}}</p>
        <div >
            <h1>{{rating_score}}</h1>
        </div>
         <ul >
            {{#each flavor_profiles}}
                <li><a href="#" >{{this}}</a></li>
            {{/each}}
         </ul>
    </div>
    {{/each}}
    </script>

and I also tried to register some helper function in script.js which did not work. This is a small hobby thing where I am just visualizing something in another way. So I don't want to use further frameworks or server side processing. The JSON gets pulled from elsewhere so I can't change how it looks. Is there any way within Handlebars to render my desired output?

CodePudding user response:

I solved it like this

script.js

    var data = JSON.parse(request.responseText, function(key, x) {
        if (key === "flavor_profiles") {
           x = x.split(',');
        return x;
        }
        return x;
     });

HTML

<ul >
     {{#each flavor_profiles}}
     <li><a href="#" >{{this}}</a></li>
     {{/each}}
</ul>

CodePudding user response:

I think little bit of j Query can help with your problem. I don't know this is what you expected.

HTML

<script id="checkin-template" type="text/x-handlebars-template">
    {{#each this}}
    <div >
    <h1>{{venue_country}}<h2>
    <p>{{venue_state}}</p>
        <div >
            <h1>{{rating_score}}</h1>
        </div>
        <ul  id="stringToList">
            {{flavor_profiles}}
        </ul>
    </div>
    {{/each}}
</script>
<div ></div>

and new function to script.js

$(document).ready(function () {
   $("[id='stringToList']").each(function () {
        let el = $(this).text().toString().split(",").map(item => `<li><a href="#" >${item}</a></li>`).join('')
        $(this).html(el)
    })
});
  • Related