Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I do a parameter based publication in Meteor and remove old subscription document?

Tags:

meteor

I want to implement a parameter based publication in Meteor but I am running into some problems.

Here is what I have.

As the user types the keyup event that subscribes to publication and passes the value of the input.

'keyup #customerSearch': function(event, template){
    var keyword = template.find('#customerSearch').value;
    if(keyword){
      if(keyword.length >= 3){
        Meteor.subscribe('sessioncustomers', keyword); 
      }
    }
  }

The publication uses this keyword to return the records.

Meteor.publish("sessioncustomers", function(keyword){
  if(keyword ){
    if(keyword.length >= 3){
      query.name  = new RegExp(regExpQuoted(keyword), 'i' );
      Customers.find(query);
    } else {
      return null;
    }
  }else{
    return null;
  }
});

The problem. It works and documents are received except when the client changes the keyword or rather as the keywords changes the publication publishes additional documents that match the keywords but the client collection never removes the old documents.

How do I get the old documents that no longer match out of the client collection?

I thought that because the parameters of the subscription had changed that the non-matching documents would be unsubscribed and only the new matching documents would be subscribed.

like image 748
Steeve Cannon Avatar asked Oct 06 '13 03:10

Steeve Cannon


2 Answers

In your keyup callback you need to "unsubscribe" to the previous publication, otherwise you'll keep the old documents.

var sessionCustomersHandler = false;
'keyup #customerSearch': function(event, template) {
  var keyword = template.find('#customerSearch').value;

  if (keyword && keyword.length >= 3)
    var newSessionCustomersHandler = Meteor.subscribe('sessioncustomers', keyword); 

  if (sessionCustomersHandler)
    sessionCustomersHandler.stop();

  sessionCustomersHandler = newSessionCustomersHandler;
}

Moreover, don't forget to check(keyword, String) in your publish function, for security.

Meteor.publish("sessioncustomers", function(keyword){
  check(keyword, String)

  if (keyword.length >= 3)
    return Customers.find({
      name: new RegExp(regExpQuoted(keyword), 'i' )
    });
});
like image 159
mquandalle Avatar answered Nov 13 '22 07:11

mquandalle


Make a local unnamed client collection

this.SessionCustomers = new Meteor.Collection(null);

Call a server method to get the results you want. Make the callback clear (remove all) and then insert to that local collection.

return Meteor.call('sessioncustomers', query, function(err, data) {
    if (err) {
      return console.log(err.message);
    } else {
        SessionCustomers.remove({});
        var item, _i, _len;

        for (_i = 0, _len = data.length; _i < _len; _i++) {
           item = array[_i];
           SessionCustomers.insert(item);
        }
    }
  });
like image 1
Jim Mack Avatar answered Nov 13 '22 09:11

Jim Mack