InquisitiveGirl
InquisitiveGirl

Reputation: 687

Iron router : Meteor JS

Initially I started by creating a route with just the _id which worked perfectly fine when I wired it up with the meteor collections. Now I'm passing in the sensor_name as the part of the url and that's a nested field in sensors so I'm passing that to the data. Code snippet for my router.js looks like this :

this.route('users', {
path: '/user/:_id/:sensor_name',
data: function () {return Users.findOne({_id: this.params._id, 
'sensors.sensor_name':this.params.sensor_name})},
});

My collection.js code looks like this :

'value': function (){ 
  var user = Users.findOne({_id:this._id});
  var sensorArr = user.sensors;
  if(sensorArr){
    var arr = [];
    sensorArr.forEach(function(entry) {
      if(entry.sensor_name == "sen1") {
      if(entry.measurements){
        console.log("cool")
        entry.measurements.forEach(function(entry1){
          arr.push(entry1.value);
          console.log(arr)
        });
      }
    }
    });
  }
  return arr;
 },

In the above code at this stage if(entry.sensor_name == "sen1") {... I want to pass in the url query string info from the router.js for which I tried using (i.e. http://localhost:3000/user/Charu/sen1 : from this I want to use sen1 )

      if(entry.sensor_name == this.sensors.sensor_name) {...

but that doesn't work.

Please suggest ideas so I can grab the url sensor name data and use it in my collections.

UPDATE :

MONGODB Schema layout

enter image description here

Upvotes: 1

Views: 60

Answers (1)

Michel Floyd
Michel Floyd

Reputation: 20227

You can simplify your route to just return the route params as an object:

this.route('users', {
  path: '/user/:_id/:sensor_name',
  data() {return { _id: this.params._id, sensor_name: this.params.sensor_name })},
});

Note that:

Users.findOne({ _id: this.params._id, 'sensors.sensor_name':this.params.sensor_name}) === Users.findOne({ _id: this.params._id })

since the search by _id is going to give you a unique result.

Furthermore searching for the user object in both the route and the helper is redundant.

Now your helper can access this._id and this.sensor_name directly. You can use $elemMatch in the projection of your .find() to extract only the matching array element(s) as follows:

value() { 
  const user = Users.findOne(this._id,
    { fields: { sensors: { $elemMatch: { 'sensors.name': this.sensor_name }}}});
  const sensorArr = user.sensors;
  let arr = [];
  sensorArr.forEach(entry =>{
    if(entry.measurements){
      entry.measurements.forEach(entry1 =>{
        arr.push(entry1.value);
      });
    }
  });
  return arr;
 },

A convenient shorthand when searching by _id is:

MyCollection.findOne({ _id: someId }) === MyCollections.findOne(someId)

Upvotes: 1

Related Questions