Getting cursor of collection using array of _id

I am making a list right now.

Users will be able to search and then click on the searched item to add the corresponding id to the their list.

This is the following code I have written.

Template.searchedItem.events

'click .addToList': function (event, template) {
    event.preventDefault();

    // _id of the List
    var listId = Template.parentData(1)._id;
    console.log(listId);
    
    // _id of the searched item
    var companyId = this._id;
    console.log(companyId);

    Meteor.call('addToList', listId, companyId, function (error, result) {
     if (error) {

     } else {

     }
    });
  }

Method

Meteor.methods({
  addToList: function (listId, companyId) {
    check(listId, String);
    check(companyId, String);

    var add = Lists.update({
      _id: listId,
      companies: {$ne: companyId}
    }, {
      $addToSet: {companies: companyId},
      $inc: {companyCount: 1}
    });

    return add;
  }
});

Object of List

list = {
  _id: listId,
  name: nameOfList
  companies: [
    // _ids of added companies
    0: 'addedCompanyId',
    1: 'someOtherAddedCompanyId',
    and so forth...
  ]
}

From here, I am trying to make a sub/pub that shows ONLY the companies that are added in list.companies.

I have no idea on howā€¦

I am thinking of something like this.

<template name = "list">
  {{#each addedCompanies}}
    something here
  {{/each}}
</template>

Template.list.helpers({
  addedCompanies: function () {
   companies = this.companies;
   return Clients.find(/*something here*/);
  }
});

Everything Iā€™ve written works so far. But I am lost in returning a cursor from an array of _ids.

Thereā€™s potentially a lot going on here!

At the moment I canā€™t see how youā€™re providing a way to make the data available to the client. You have hinted that it could go in the Meteor.call callback (you return add from the method). Alternatively, it could be via a pub/sub.

Itā€™s important to understand how you go about getting updates when the data changes (using the callback will not help if another user changes the data). So, my suggestion would be to use pub/sub, which will give you reactive updates with little effort.

Using pub/sub means you do not need to return data from the method, nor try to handle it in the callback. You should still check for error.

I have used a Session variable in these snippets. In reality I would probably use a locally scoped ReactiveVar if I was implementing this, but without a full understanding of your code itā€™s just easier to explain with a global. Donā€™t shoot me :wink:!

Publication (server)

Meteor.publish ('myList', function(listId) {
  // security checks here!
  return Lists.find(listId);
});

Subscription (client)

Template.list.onCreated(function() {
  var self = this;
  this.autorun(function() { // run once, then every time the reactive list id changes
    this.subscribe('myList', Session.get('listId')); // (re)subscribe with a (new) list id
  });
});

Template helper

You do not need to return a cursor in a template helper - you can return an array. So you could, for example, do:

Template.list.helpers({
  addedCompanies: function () {
    return List.findOne().companies; // There is only one list per listId
  }
});

You will also need a way to set and change the value of the Session ā€˜listIdā€™. You could do that in a higher level template event handler.

BTW, your ā€œObject of Listā€ is syntactically incorrect. I think it should be:

list = {
  _id: listId,
  name: nameOfList
  companies: [
    // _ids of added companies
    'addedCompanyId',
    'someOtherAddedCompanyId',
    and so forth...
  ]
}

HTH :smile:

1 Like

If your list is not too long, you can get a cursor using Collection.find({_id: {$in: list}}).

Donā€™t abuse this by sending a list thatā€™s hundreds of elements, though.

1 Like

Thank you for your response! I will try it with this method and get back to you :slight_smile:

Ah, I will have to test out $in and see if Iā€™m abusing it or not. Btw, loving your user-status package. Itā€™s included in all of my projects!