Best way to execute update call when changing input field value in Meteor JS?

A hypothetical example - you have a collection of "Items", where each item has a quantity and price stored in db.

This quantity is an input field.   

We want the database to be updated when the quantity changes - without the send button. There are several ways around this. Two examples:

  • Update db to "changed":

    'change input.qty': function (evt) {
        var qty = $(evt.target).val();
        if (qty==null){
            qty=0;
        };
        Items.update(this._id,{$set:{quantity: Number(qty)}});
    },
    
  • Update db to "keyup":

    'keyup input.qty': function (evt) {
        var qty = $(evt.target).val();
        if (qty==null){
            qty=0;
        };
        Items.update(this._id,{$set:{quantity: Number(qty)}});
    },
    

1 is more efficient - it only makes an update call once, after the user clicked outside the input field. However, this is worse because updates do not appear on the page as you type. (For example, say the price field is calculated reactively based on your input quantity)

2 - , (.. 103.58 FIVE )

?

+4
4

​​ :

var handle = null;
------------------------
'input input.qty': function (evt) {
    var self = this;
    if (handle)
        clearTimeout(handle);
    handle = setTimeout(function () {
        var qty = $(evt.target).val();
        if (qty==null){
            qty=0;
        };
        Items.update(self._id,{$set:{quantity: Number(qty)}});
    }, 500);
},

500, . , 500 .

, , .

+2

, _.throttle .

'keyup input.qty': _.throttle(function (evt) {
  ...
}, 350),

_.throttle , , .

350 , , .

+5

Plagiarising @Hubert OG , "debounce", "" "". (_.debounce , @Dave .)

, _.debounce.

'input input.qty, change input.qty': _.debounce(function (evt) {
  ...
}, 350),

_.debounce , , ( , )

+3
source

Both seem to be good solutions. The first, in my opinion, is better - keyup also logs things like hitting the enter key or other keys. Since I have several elements with several quantity fields, here is what I ended up with:

var handle = [];

'input input.qty': function (evt) {
    var id = this._id;
    if (handle[id]){
      clearTimeout(handle[id]);
    }
    handle[id] = setTimeout(function () {
      var qty = $(evt.target).val();
      Items.update(id,{$set:{quantity: Number(qty)}});
    }, 750);
}
0
source

All Articles