Shariq Ansari
Shariq Ansari

Reputation: 4641

Show key value pair in table using meteor and mongo db

In mongodb i have json values like and it is not fixed. Some time it will be only 2 or 3 and sometime it will be very large.

  {"_id" : "p83oZAo7fdhNuDD34",
"Active Template Name" : "Windows Mobile",
"ProductId" : "456",
"Subcategory" : "on",
"Size" : "on",
"Material" : "A",
"Price" : "2345",
"Combo Id" : "67u",
"Color" : "red",
"Status" : "Pending"
},
{
  "_id" : "p83oZAo7fdhNuDD34",
"Material" : "A",
"Price" : "2345",
"Combo Id" : "67u",
"Color" : "red",
"Status" : "Pending"
}

I want to show all keys like (id, Active Template Name, ProductID .......) as table header and values (p83oZAo7fdhNuDD34,Windows Mobile,456 .......) in tbody.

I am not getting the exact way to perform this in meteor. My collection name is products and Html code is bellow.

    <template name="productvalue">
     <table>

     </table>
    </template>

Upvotes: 4

Views: 448

Answers (2)

SylvainB
SylvainB

Reputation: 4820

If you want to display a table with all the possible properties in the header, and each row with each column filled or not whether the property is defined or not for the document in that row, then you will need to:

  1. Ahead of time (in onCreated or onRendered), find all possible properties for your dataset, order them, and store them in a "header" object accessible to your helpers. (either in Session or using a reactive variable) Make it reactive if necessary, using this.autorun().
  2. Then, do the same as above, except just returning the stored ordered list for tableHeader
  3. And for rowContent, iterate over your stored header and fill an array with empty strings for each undefined field in the current document

Example:

function getHeader(products) {
  var header = {};
  for (var key in products) {
    for (var property in products[key]) {
        header[property] = true;
    }
  }
  return Object.keys(header);
}

Template.productvalue.onRendered(function () {
  var products = Products.find().fetch();
  Session.set('header', getHeader(products));
  this.autorun(function () {
    var products = Products.find().fetch();
    Session.set('header', getHeader(products));
  });
});

Template.productvalue.helpers({
  'tableHeader': function () {
    return Session.get('header');
  },
  'rowContent': function (document) {
    var row = [];
    var header = Session.get('header');
    for (var key in header) {
      row.push(document[header[key]] || "");
    }
    return row;
  }
});

And in template:

<template name="productvalue">
 <table>
  <thead>
   {{#each tableHeader}}
    <th>{{this}}</th>
   {{/each}}
  </thead>
  <tbody>
   {{#each products}}
    <tr>
     {{#each rowContent this}}
      <td>{{this}}</td>
     {{/each}}
    </tr>
   {{/each}}
  </tbody>
 </table>
</template>

I still recommend using a reactive variable instead of Session, but the demonstration is complicated enough as it is.

Upvotes: 1

saimeunt
saimeunt

Reputation: 22696

Use a {{#each}} block helper to iterate over your collection products.

<template name="productvalue">
  <table>
    <thead>
      <th>Id</th>
      <th>Active Template Name</th>
      <th>ProductId</th>
      [...]
    </thead>
    <tbody>
      {{#each products}}
        <tr>
          <td>{{_id}}</td>
          <td>{{activeTemplateName}}</td>
          <td>{{ProductId}}</td>
          [...]
        </tr>
      {{/each}}
    </tbody>
  </table>
</template>

You also need to define helpers to rename the problematic keys containing invalid Spacebars characters.

Template.productvalue.helpers({
  products: function(){
    return Products.find();
  },
  activeTemplateName: function(){
    return this["Active Template Name"];
  },
  [...]
});

Upvotes: 2

Related Questions