Meteor: Iterating over an Object inside of a Collection

- 1 answer

Ad

I've run into this problem a few times, and it's slowly driving me insane. Short question: When given a collection which contains an Object as a field, how can we iterate over that object in a template.

Each entry in the collection can look like this:

{
    "_id" : "jsWmXTvocbSMM5JAF",
    "userId" : "gcko4Eo3YtZaWa8aj",
    "gameId" : "eduzNj8kWv7TdiEuE",
    "scores" : {
        "team1" : 3,
        "team2" : 1,
        "losses" : 7
    }
}

We can easily access {{userId}} or {{gameId}} in the template, but of course {{scores}} just displayed [object Object], which we expected.

I tried using {{#each scores}}, which I have used with arrays before, but of course, that throws an error:

{{#each}} currently only accepts arrays, cursors or falsey values.

Then I tried to be clever (rarely a good idea) and push a bunch of Objects into an array, and then return that to the template:

Template.scorePad.helpers({
    scoresArray: function () {
        var arr = [], scores = this.scores;
        for (var key in scores) {
            var obj = {};
            obj[key] = scores[key];
            arr.push(obj);
        }
        return arr;
    }
}

I'm not sure why I thought that would be a good idea, because this just supplies the template with an array looking like this:

[{team1: 3}, {team2: 1}, {losses: 7}]

Which, yeah, great.. I can #each over it, but it just prints out object Object three times. As expected. But here I am, covering all the bases.

There is an open issue about this (regarding not being able to use @key with #each) at the Meteor github, but I'm really hoping someone has a simple solution.

This question is sort of close to what I'm doing, but not at all the same.

I also tried #with, with basically the same results.

Basically, I'm looking for an elegant "Meteor" way of doing this, if one even exists. Clearly I'm not an expert. So what do?

EDIT to answer the comments: To clarify, in the template the ideal solution (which doesn't work) would be use something like this in my html, and iterate over each key:value pair inside scores in the collection data:

<div> {{#each scores}} {{this.key}} {{this.value}} {{/each}} </div>

and iterate over each key:value pair inside scores in the collection data.

Ad

Answer

Ad

Can you try this:

Template.scorePad.helpers({
scoresArray: function () {
    var arr = [], scores = this.scores;
    for (var key in scores) {
        var obj = {};
        obj.key = key;
        obj.value = scores[key];
        arr.push(obj);
    }
    return arr;
  }
}

And iterate it like this:

<div>
{{#each scores}}
    {{this.key}}
    {{this.value}}
{{/each}}
</div>
Ad
source: stackoverflow.com
Ad