Access an object's property names in a Blaze template
Asked Answered
W

2

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.

Wiredraw answered 4/7, 2015 at 12:28 Comment(0)
Z
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}}
Zeuxis answered 4/7, 2015 at 12:40 Comment(4)
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.Wiredraw
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: github.com/meteor/meteor/issues/3884Zeuxis
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.Wiredraw
Updated my answer. I didn't use _.pairs because I couldn't figure out how to access specific array indexes using spacebars.Zeuxis
B
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.

Blitz answered 4/7, 2015 at 13:43 Comment(0)
Z
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}}
Zeuxis answered 4/7, 2015 at 12:40 Comment(4)
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.Wiredraw
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: github.com/meteor/meteor/issues/3884Zeuxis
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.Wiredraw
Updated my answer. I didn't use _.pairs because I couldn't figure out how to access specific array indexes using spacebars.Zeuxis

© 2022 - 2024 — McMap. All rights reserved.