3

This is somewhat of a part 2 to my last question. Thanks to some helpful folks, I now have a document that looks like this:

{ "_id" : "dndsZhRgbPK24n5LD", "createdAt" : ISODate("2014-11-26T16:28:02.655Z"), "data" : { "cat1" : 493.6, "cat2" : 740.4 }, "owner" : "GiWCb8jXbPfzyc5ZF", "text" : "asdf" }

Specifically, I want to extract the value from each property of data in Spacebars and iterate over it to create a table - and I know the number of fields in object data but the number can vary. Yes, I know this has been asked before but nobody has seemed to be able to give a satisfactory answer that works. But as a final result I would like to display the whole document in a row, like this

<tbody>
  <tr>
    <td>493.6</td>
    <td>740.4</td>
    <td>asdf</td>
</tbody>

Thanks in advance for any help.

Community
  • 1
  • 1
Max Isom
  • 98
  • 3
  • 11

1 Answers1

5

Here's complete working example:

Cats = new Mongo.Collection(null);

Meteor.startup(function() {
  Cats.insert({
    data: {
      cat1: 100,
      cat2: 200
    },
    text: 'cat1'
  });

  Cats.insert({
    data: {
      cat1: 300,
      cat2: 400,
      cat3: 500
    },
    text: 'cat2'
  });
});

Template.cats.helpers({
  cats: function() {
    return Cats.find();
  },

  // Returns an array containg numbers from a cat's data values AND the cat's
  // text. For example if the current cat (this) was:
  // {text: 'meow', data: {cat1: 100, cat2: 300}}, columns should return:
  // [100, 200, 'meow'].
  columns: function() {
    // The current context (this) is a cat document. First we'll extract an
    // array of numbers from this.data using underscore's values function:
    var result = _.values(this.data);

    // result should now look like [100, 200] (using the example above). Next we
    // will append this.text to the end of the result:
    result.push(this.text);

    // Return the result - it shold now look like: [100, 200, 'meow'].
    return result;
  }
});
<body>
  {{> cats}}
</body>

<template name='cats'>
  <table>
    {{#each cats}}
      <tr>
        {{#each columns}}
          <td>{{this}}</td>
        {{/each}}
      </tr>
    {{/each}}
  </table>
</template>
David Weldon
  • 63,632
  • 11
  • 148
  • 146
  • Please see my updated question. The problem is that I not only want to display the `data` object, but also the rest of the document. – Max Isom Dec 04 '14 at 02:07
  • I updated the answer with a tested solution. Is that what you are looking for? I'm unclear from the question if each document has the same structure or if the number of fields varies. – David Weldon Dec 04 '14 at 15:12
  • The number of fields in `data` can vary. That combined with displaying the rest of the document makes a knot. – Max Isom Dec 04 '14 at 17:54
  • Okay - try the updated version. There are a million different ways to write the `columns` helper but the overall structure should help you implement a solution. – David Weldon Dec 04 '14 at 19:04
  • Thanks! Works perfectly now. I didn't know you could reference `this` in a helper function. – Max Isom Dec 05 '14 at 00:22
  • Do you have a question about the answer? If so, I'm happy to help. – David Weldon Sep 21 '15 at 19:28
  • your `columns` template helper is not straightforward; it's unclear whether youre using Meteor conventions or javascript methods. – redress Sep 21 '15 at 19:33
  • Okay, I updated the answer with fully commented code for `columns`. Let me know if that helps or if you need additional clarification. – David Weldon Sep 21 '15 at 19:52