Taylorsuk
Taylorsuk

Reputation: 1449

Create HTML list from array of Objects in JS

I am using SparkPost to display a list of exercises that have been sent to a client. The aim is to create a HTML string that can be sent to the API as substitution_data.

An example of the data I need to split down is:

[{
    "exerciseName": "4 Point Kneeling Lumbar",
    "Params": [{
        "param": "Sets",
        "childParam": "1"
    }, {
        "param": "Reps",
        "childParam": "1"
    }]
}, {
    "exerciseName": "Side Flexion",
    "Params": [{
        "param": "Sets",
        "childParam": "1"
    }, {
        "param": "Reps",
        "childParam": "1"
    }]
}]

I need to create a string like this:

<ul>
  <li>4 Point Kneeling Lumbar, Sets: 1, Reps: 10</li>
  <li>Side Flexion, Sets: 1, Reps: 12</li>
</ul>

i.e

var subData = '<ul><li>4 Point Kneeling Lumbar, Sets: 1, Reps: 10</li><li>Side Flexion, Sets: 1, Reps: 12</li></ul>';

I have created a CodePen that shows the first level (exercise Name) however I am unsure how to access the params and display in the desired structure.

Upvotes: 2

Views: 7702

Answers (2)

sielakos
sielakos

Reputation: 2404

You need to loop over Params and then use map and join as you did with parent elements.

You might also consider using some template language for that kind of tasks. As it is easier to do so with them.

var list = [{
    "exerciseName": "4 Point Kneeling Lumbar",
    "Params": [{
        "param": "Sets",
        "childParam": "1"
    }, {
        "param": "Reps",
        "childParam": "1"
    }]
}, {
    "exerciseName": "Side Flexion",
    "Params": [{
        "param": "Sets",
        "childParam": "1"
    }, {
        "param": "Reps",
        "childParam": "1"
    }]
}];

var html = list.map(function (element) {
  return '<li>' + element.exerciseName + ', ' +
    formatParams(element.Params) + '</li>';  
}).join('');

document.getElementById('target').innerHTML = html;


function formatParams(params) {
  return params.map(function (param) {
    return param.param + ':' + param.childParam;
  }).join(', ');
}
<div id="target"></div>

You might consider nunjucks as simple and easy to use template language. Generally you should keep template in separate files and fetch them with ajax, but for simplicity I keep it in string and that might make it a bit harder to read.

var list = [{
    "exerciseName": "4 Point Kneeling Lumbar",
    "Params": [{
        "param": "Sets",
        "childParam": "1"
    }, {
        "param": "Reps",
        "childParam": "1"
    }]
}, {
    "exerciseName": "Side Flexion",
    "Params": [{
        "param": "Sets",
        "childParam": "1"
    }, {
        "param": "Reps",
        "childParam": "1"
    }]
}];

var template = '<ul>{% for item in list %} ' +
    '<li>{{ item.exerciseName }}, ' +
    '{% for param in item.Params %}' +
    '  {{param.param}}: {{param.childParam}} {% if not loop.last %} , {% endif %}'+
    '{%endfor%} '+
    '</li>{%endfor%}</ul>';

document.body.innerHTML = nunjucks.renderString(template, { list: list});
<script src="https://cdnjs.cloudflare.com/ajax/libs/nunjucks/2.4.2/nunjucks.js"></script>

It might seems as longer and more complicated solution than using pure JavaScript, but in long run as your data model get more and more complicated it would make things easier. Ofc for such simple data it more complicated, but in real life you hardly ever have such simple data to display.

Upvotes: 7

blex
blex

Reputation: 25634

You just need two nested loops:

var list = [{
  "exerciseName": "4 Point Kneeling Lumbar",
  "Params": [{
    "param": "Sets",
    "childParam": "1"
  }, {
    "param": "Reps",
    "childParam": "1"
  }]
}, {
  "exerciseName": "Side Flexion",
  "Params": [{
    "param": "Sets",
    "childParam": "1"
  }, {
    "param": "Reps",
    "childParam": "1"
  }]
}];

var html = '';

for (var i = 0, l = list.length; i < l; i++) {
  html += '<li>' + list[i].exerciseName;
  for (var j = 0, k = list[i].Params.length; j < k; j++) {
    html += ', ' + list[i].Params[j].param + ': ' + list[i].Params[j].childParam
  }
  html += '</li>';
}

document.body.innerHTML = '<ul>' + html + '</ul>';

Upvotes: 4

Related Questions