6

Say I have a helper that looks like this:

Template.profile.helpers({
  info: {
    Name: 'Bob Dinkleberg',
    Age: 45,
    Location: 'Earth, Milky Way'
  }
});

I want to put this info in a <ul>. Here is some pseudo-code:

<template name="profile>
  <ul>
    {{#each}}
      <li> {{key}}: {{property}} </li>
    {{/each}}
  </ul>
</template>

Forgive me if this is trivial, I am new to Meteor and Blaze, and I haven't been able to find a solution online.

Luke
  • 5,567
  • 4
  • 37
  • 66

2 Answers2

4

If you want to loop through an objects properties and values as you requested, you can do it generic by:

Template.content.onCreated(function() {
  this.properties = new ReactiveVar({
    Name: 'Bob Dinkleberg',
    Age: 45,
    Location: 'Earth, Milky Way'
  });
});

Template.content.helpers({
  keys: function () {
    return Object.keys(Template.instance().properties.get());
  },
  key_value_pair: function() {
    return { key: this, value: Template.instance().properties.get()[this] };
  }
});

and with this template

<body>
  <h1>Property Loop</h1>
  <ul>
  {{> content}}
  </ul>
</body>

<template name="content">
  {{#each keys}}
    {{> property key_value_pair }}
  {{/each}}
</template>

<template name="property">
  <li>{{key}}: {{value}}</li>
</template>

I prepared this MeteorPad for you which is a running example:

http://meteorpad.com/pad/24MGwbuMNCcXCC7EW/PropertyLoop

Cheers, Tom

P.S.: It is not necessary to create the object as a ReactiveVar if there a never changes to its values. But by doing it as a ReactiveVar the form is als reactivly updated, when object content will change.

Tom Freudenberg
  • 1,337
  • 12
  • 31
2

This will be helpful:

http://meteorcapture.com/spacebars/

You want to use {{#with}}.

<template name="profile">
  <ul>
    {{#with info}}
      <li>{{Name}}</li>
      <li>{{Age}}</li>
      <li>{{Location}}</li>
    {{/with}}
  </ul>
</template>

While your helper code is correct:

Template.profile.helpers({
  info: {
    Name: 'Bob Dinkleberg',
    Age: 45,
    Location: 'Earth, Milky Way'
  }
});

I personally like to make a habit of mapping the name of the helper to a function that returns something.

Template.profile.helpers({

  info: function(){

    return {
      Name: 'Bob Dinkleberg',
      Age: 45,
      Location: 'Earth, Milky Way'
    };

  }

});

EDIT

Template.content.helpers({

  info: function(){
    var obj = {
      Name: 'Bob Dinkleberg',
      Age: 45,
      Location: 'Earth, Milky Way'
    };
    var arrayOfObjects = [];

    // creating an array of objects
    for (key in obj){
      arrayOfObjects.push({key: key, value: obj[key]});
    };
    console.log("This is the array of objects: ", arrayOfObjects);
    return arrayOfObjects;
  },

});

HTML:

{{#each info}}
    {{value}}
{{/each}}
fuzzybabybunny
  • 5,146
  • 6
  • 32
  • 58
  • Is there a way to access an object's property names programatically? (I don't want to have to actually write 'Name, Location....' in my markup. I'd rather just iterate over the object and grab the key.) For now, we can assume I don't care about order. – Luke Jul 04 '15 at 12:53
  • 1
    You can iterate over arrays because arrays keep order. Iterating over an object is kind of weird because the order is not guaranteed - the values could show up in different orders on each loop. But if you must, it's an open issue and there is a workaround by basically turning the object into an array: https://github.com/meteor/meteor/issues/3884 – fuzzybabybunny Jul 04 '15 at 12:56
  • Using that workaround, can you give me an example of how I would access the individual elements in the nested arrays? If I return `_pairs(object)` in my helper and I access `{{this}}` inside the `{{#each}}` block, I get the current array, but If I access `{{this[0]}}`, I still just get the same array for some reason. – Luke Jul 04 '15 at 13:30
  • Updated my answer. I didn't use `_.pairs` because I couldn't figure out how to access specific array indexes using spacebars. – fuzzybabybunny Jul 04 '15 at 23:12