MiniMongo and Spacebars - Accessing properties deep within an object?

While Mongo supports this, unfortunately MiniMongo does not:

Template.foo.helpers({
  things: function() {
    var stateVal = 'TX'; //test value
    return Things.find({states: {$elemMatch: {state: stateVal}}},
      {
        fields: {
          name: 1,
          weight: 1,
          states: {$elemMatch: {state: stateVal}}
        }
      }
    );
  }
});

Typical data for a Thing:

{
  name: 'some object',
  weight: 200,
  states: [
    {state: 'TX', price: 2.50},
    {state: 'WA', price: 3.50}
  ]
}

I only want to have the data for Texas returned in the cursor, so I can (somehow) access its price via Spacebars:

{{#each things}}
  <li>{{name}} costs ${{states.price}}</li>
{{/each}}

I know that syntax is wrong. I just don’t know how to dig that deep into an object. How would I do this?

if you want to pick one element our of an embedded array, it is true that minimongo doesn’t support the $ operator
however, you can filter the array on the client using standard array functions

I don’t see how I’d do that.

you fetch the cursor and manipulate the document:

var things = Things.find({ states: { state: 'TX' } }).fetch(); // filter out irrelevant things

// map fetched things to a new array of things where #states is actually a single object
return _(things).map(function(thing) { 
   thing.states = _(thing.states).find(function(state) { 
    return state.state == 'TX'; 
   }); // return only the one desired state
   return thing;
});

of course, this is one way to do it -
my answer was as close as possible to your initial suggestion, but I’d consider filtering out the states at the publish stage by creating a “manual” publication (i.e. not just return a cursor)

If I go even more backwards, have you considered modeling Thing.states as a dictionary (state initials are key) instead of an array? this way you could easily get what you wanted with this query:

Things.find({}, { fields: { name: 1, 'states.TX': 1 } })
1 Like

@chenroth I was totally approaching it the wrong way. Thanks!