-2

I have a JSON file with the following structure:

{ ShippingDate: '06.09.2016',
    'Order ID': 200003946,
    ID: 751,
    Product: 'Mobile Phone'},
  { ShippingDate: '06.09.2016',
    'Order ID': 200003946,
    ID: 751,
    Product: 'TV'},
  { ShippingDate: '06.09.2016',
    'Order ID': 200003946,
    ID: 751,
    Product: 'Batteries'},
  { ShippingDate: '06.09.2016',
    'Order ID': 200003926,
    ID: 752,
    Product: 'Car'},

So the first three entries are an order of the same customer. The fourth one is an order of another customer.

I know want to use a handlebars.js template to create an html file with each order including the items the order has. So I prepared this template:

<div class="header">
    <h1>{{ID}}</h1>
</div>
<div class="body">
    <ul>
      {{#each Product}}
        <li>{{this}}</li>
      {{/each}}
    </ul>
</div>

I now have the problem, that I need to prepare that kind of data for the template. And here I stumbled across some problems. My code goes like this

...
var f = fs.readFileSync('data.json').toString();
var lines = JSON.parse(f);
var items = [];
//prepare products of one customer and put them into an array
for (var key in lines) {

  var line = lines[key];
  var nextLine = lines[(parseInt(key)+1)];

  if (nextLine !== undefined && line !== undefined) {
    if (line['Order ID'] !== nextLine['Order ID']) {
        items.push('Product: ' + line.Product);
    }//if   
  }//if
}//for

var data = lines;
fs.readFile(template.html, 'utf-8', function(error, source){
  var template = handlebars.compile(source);
  var html = template(data);
  console.log(html)
});

This is not working - how can I prepare my array of items so that I can access these products with the products variable in my template? Additionally I need to add information like ID and Shipping Date to that json string. The data format must look like this:

var data = {
  ShippingDate: '06.09.2016',
  ID: '751',
  Product: ['Mobile Phone', 'TV', 'Batteries']
}

Anybody can help here?

Torben
  • 5,388
  • 12
  • 46
  • 78
  • Possible duplicate of [Access / process (nested) objects, arrays or JSON](http://stackoverflow.com/questions/11922383/access-process-nested-objects-arrays-or-json) – Liam Sep 08 '16 at 08:36

1 Answers1

1

Here is a way to do it :

var data = [{
    "ShippingDate": "06.09.2016",
    "Order ID": 200003946,
    "ID": 751,
    "Product": "Mobile Phone"
}, {
    "ShippingDate": "06.09.2016",
    "Order ID": 200003946,
    "ID": 751,
    "Product": "TV"
}, {
    "ShippingDate": "06.09.2016",
    "Order ID": 200003946,
    "ID": 751,
    "Product": "Batteries"
}, {
    "ShippingDate": "06.09.2016",
    "Order ID": 200003926,
    "ID": 752,
    "Product": "Car"
}];

var newData = {};

data.forEach(function(item) {
    if (typeof newData[item.ID] === 'undefined') {
        newData[item.ID] = {
            ShippingDate: item.ShippingDate,
            ID: item.ID,
            Product: []
        };
    }

    newData[item.ID].Product.push(item.Product);
});

newData = Object.values(newData);
vincenth
  • 1,732
  • 5
  • 19
  • 27
  • Thanks @vincenth - do you also have an example in JavaScript? – Torben Sep 08 '16 at 07:23
  • @Torben, I updated my answer and added a js example. – vincenth Sep 08 '16 at 07:37
  • Thanks so much. This brings me forward. One question though. I have now implemented the same as you have. The result is: { '200003908': { ShippingDate: '06.09.2016', ID: 200003946, Product: [ 'Mobile Phone', 'TV', 'Batteries' ] } } How can I change it, so that the first level with the ID is gone and the result is only: { ShippingDate: '06.09.2016', ID: 200003946, Product: [ 'Mobile Phone', 'TV', 'Batteries' ] } Thats what I am looking for. Thanks so much for your help, my brain is frozen :/ – Torben Sep 08 '16 at 08:28
  • @Liam, you're right, I answered too quickly late at night, my mistake. I removed it. Thanks for your input. – vincenth Sep 08 '16 at 08:39
  • Thanks for your help. I get this error: console.log(Object.values(newData)); ^ TypeError: Object.values is not a function – Torben Sep 08 '16 at 08:41
  • @Torben The method is not implemented in your browser, you're either not using chrome or firefox, or using an older version. You can add this function in your script, it will add the method if it does not exists (cf. https://github.com/tc39/proposal-object-values-entries/blob/master/polyfill.js) : if (!Object.values) { Object.values = function values(O) { return reduce(keys(O), (v, k) => concat(v, typeof k === 'string' && isEnumerable(O, k) ? [O[k]] : []), []); }; } – vincenth Sep 08 '16 at 08:45
  • Thanks. I got it now! – Torben Sep 08 '16 at 09:36