best method to build table headings and data separately using same json in underscore.js?

164 views Asked by At

I'm working on my first site using client-side templating, and so far so good. I'm just looking to achieve the best performance for the code below.

I'm given json in this format:

[
    {
        "slidenumber": "slide0",
        "title": "Sample Data 1",
        "slideDelay": "2000",
        "months": [
            {
                "Jan": "10.3",
                "Dec": "65",
                "Nov": "87",
                "Oct": "80",
                "Sep": "70",
                "Aug": "100"
            }
        ]
    },
    {
        "slidenumber": "slide1",
        "title": "Sample Data 2",
        "slideDelay": "2000",
        "months": [
            {
                "Jul": "10",
                "Jun": "20",
                "May": "30",
                "Apr": "40",
                "Mar": "50",
                "Feb": "60"
            }
        ]
    }
]

and using the underscore.js template below:

     _.each(slides, function(slide){ %>
       <li data-slide-delay="<%= slide.slideDelay %>">
         <h1><%= slide.title %></h1>
          <table class="table">
            <thead>
              <tr>
                <% 
                  _.each( slide.months, function(month) {
                    if (_.isObject(month)) {
                     _.each(month, function(value, key) {%>
                        <th><%= key %></th>
                      <%}) 
                    }
                  });%>
            </tr>
          </thead>
          <tbody>
              <tr>
                <% 
                  _.each( slide.months, function(month) {
                    if (_.isObject(month)) {
                     _.each(month, function(value, key) {%>
                        <td><%= value %></td>
                      <%}) 
                    }
                  });%>
            </tr>
          </tbody>
        </table>
      </li>

Basically, I'm building a slideshow using the data above, so each "slide" has specific fields title, delay, etc., months on the other hand has data inside of it. I'm building an <li> for each slide and within in that a horizontal <table>, in that table I'm building <th> for the month (i.e. Jan, Feb, Mar, etc.) and then I'm separating the month value in <td>'s

Rather than do two _.(each statements with the same data (but echoing different values) as I'm doing above, what's the best method to achieve the desired output?

1

There are 1 answers

1
JF Dion On BEST ANSWER

If you preprocess your JSON data before using it for printing you can lower your number of nested _.each.

You will still have to use two _.each statements to display your data.

The real benefit of doing this, is that you can centralize your data processing and you decouple your data from your display by adding a level of abstraction. If your data structure change overtime, you would only have to modify the data processing part and your "view" would remain the same

var headers = [];
var content = [];
var rows = 0;
_.each(slides, function(slide){
    if (rows % 2 == 0) {
        content.push([])
    }
    _.each(slide.months, function(month) {
        if (_.isObject(month)) {
            _.each(month, function(value, key) {
                headers.push(key);
                content[content.length - 1].push(value);
            })
        }
        rows += 1;
    })
});

console.log(headers);
console.log(content);

The headers part would be the months label and the content part would contain all your rows of data in the form of nested arrays of data.

* I used a row counter to merge the two parts of the year (from slide0 and slide1) with a modulus, but you might have to add some validation for this section to make sure you remain coherent in your table