Skip to content Skip to sidebar Skip to footer

Cannot Use 'in' Operator To Search For 'sth' In Undefined

Here is my code: . . keydown: function(ev) { clearTimeout( $(this).data('timer') ); if ( 'abort' in $(this).data('xhr') ) $(this).data('xhr').abort(); // error here

Solution 1:

The issue here is that the undefined value does not have any properties. You need to perform a check on the return value of data() to check that it isn't undefined.

var xhr = $(this).data('xhr');
if(typeof xhr !== 'undefiend' && xhr.abort) {
    // do your code here
}

Replace your if statement with the above 4 lines of code.


Solution 2:

Change from:

if ('abort' in $(this).data('xhr') ) $(this).data('xhr').abort(); 

to:

if ($(this).data('xhr') && $(this).data('xhr').abort) {
  $(this).data('xhr').abort(); 
}

Problem was simply checking if object has xhr element. By default it does not exist so it's undefined, and you were asking JS engine to find an element in undefined information that was causing error.

So that's why I added to check if it has .data('xhr') because for JS undefined is treated as false and after that I checked if data('xhr') has abort attribute.

By the way if you want to stop timer when key is pressed it's better to just clear timeout and it will not run AJAX call, so no need to put XHR object to element's data storage:

if($(this).data('timer')) {
  clearTimeout($(this).data('timer'));
}

var timer = setTimeout(function() {
    $.ajax({
        url :  '/files/tags_autocomplete.php',
        dataType : 'JSON',
        success : function (tags) {
          $("ul").html(tags.output);
        }
    });
}, 500);

$(this).data('timer', timer);

or even simpler (without data storage):

if(window.autocompleteTimer) {
  clearTimeout(window.autocompleteTimer);
}

window.autocompleteTimer = setTimeout(function() {
    $.ajax({
        url :  '/files/tags_autocomplete.php',
        dataType : 'JSON',
        success : function (tags) {
          $("ul").html(tags.output);
        }
    });
}, 500);

Solution 3:

The issue is that if the user types again before 500ms has passed, $(this).data('xhr') would be undefined, as it's not yet set to the ajax request.

As we can't use the in operator on undefined, only on objects, the correct solution to both clear the timeout and abort any pending requests, would be to just check if $(this).data('xhr') has been set, and is an object, before checking if it has an abort property

keydown: function(ev) {
  var self = $(this);

  clearTimeout(self.data('timer'));

  if (typeof self.data('xhr') === 'object' && 'abort' in self.data('xhr')) {
    self.data('xhr').abort();
  }

  var timer = setTimeout(function() {
    self.data('xhr', $.ajax({
      url: '/files/tags_autocomplete.php',
      dataType: 'JSON',
      success: function(tags) {
        $("ul").html(tags.output);
      }
    }));
  }, 500);

  self.data('timer', timer);

Post a Comment for "Cannot Use 'in' Operator To Search For 'sth' In Undefined"