0

I Am looking for a way to proper call this inside function now i have quick hack var that = $(this); but i am sure that there is propper way of doing it. How i can avoid this hack?

This is input field which i use to get var and inspect Typing Interval

<input type="text" data-package="pink" class="js-p-input">

this i my code:

var cCalc = (function ($) {
    var s;
    return {
        settings: {
            typingTimer: "",
            doneTypingInterval: 300,
            $inputs: $(".js-p-input"),

        },

        init: function () {
            s = this.settings;
            this.bindUIActions();
        },

        bindUIActions: function () {

            //on keyup, start the countdown
            s.$inputs.on('keyup', function () {
                var that = $(this);                
                clearTimeout(s.typingTimer);               
                s.typingTimer = setTimeout(function() {
                    cCalc.doneTyping(that, that.data("package"));
                }, s.doneTypingInterval);
            });

            s.$inputs.on('keydown', function () {
                clearTimeout(s.typingTimer);
            });

        },


        doneTyping: function ($input, packageName) {
            console.log('done!');
            cCalc.getValues($input.val(), packageName);
        },

    };

})(jQuery);

cCalc.init();
Ponciusz
  • 127
  • 2
  • 16
  • it doesn't work with $(this), because you are in setTimeout, so this has changed – progrAmmar Jun 15 '16 at 08:34
  • I think this is the right way to pass a 'this' variable to another function. Similar question: http://stackoverflow.com/questions/11366643/how-do-i-change-scope-of-this-in-setinterval-and-settimeout-functions – Jaapze Jun 15 '16 at 08:41
  • `setTimeout(function() {...}.bind(this), s.doneTypingInterval);` EDIT: but nothing is wrong with using a closure as you do in your code. Other way would be: `setTimeout(cCalc.doneTyping, s.doneTypingInterval, $(this), $(this).data("package"));` even passing `$(this).data("package")` seems redundant because inside `doneTyping()` method, you can get data without passing it as parameter: `$input.data('package')` – A. Wolff Jun 15 '16 at 08:44

2 Answers2

0

There is nothing wrong with using that "hack", it is standard operating procedure. See also here What is the difference between call and apply? for even more "hacky" stuff with "this" that is standard.

Community
  • 1
  • 1
Adder
  • 5,525
  • 1
  • 18
  • 47
0

As others have pointed out, there's not really anything wrong with using a closure but you could alternatively bind "this" into the timeout function scope like so:

s.$inputs.on('keyup', function () {

  clearTimeout(s.typingTimer);

  s.typingTimer = setTimeout(function() {

    cCalc.doneTyping($(this), $(this).data("package"));

  }.bind(this), s.doneTypingInterval);

});
atomless
  • 1,244
  • 14
  • 15