Search code examples
javascriptangularjstimeoutangular-datatables

Why i need to use timeout?


I am using AngularJS and angular-datatable library. I need to invoke modal on click on row. Here is my part of code:

  function rowCallback(nRow, aData, iDisplayIndex, iDisplayIndexFull) {
    // Unbind first in order to avoid any duplicate handler (see https://github.com/l-lin/angular-datatables/issues/87)
    $('td', nRow).unbind('click');
    $('td', nRow).bind('click', function() {
      console.log(aData.title);
      $timeout(function(){
        Modal.showModal({
         template : 'views/Modal.html',
         Data : aData
         });
      }, 0);
    });
    return nRow;
  }

console.log function works fine any way, but invoking modal function works as expected only when it wrapped in timeout. So can someone explain why this happening? Why only first function works good? I will be grateful for any explanations.


Solution

  • The reason you need the $timeout, is because you're using a jQuery event with an angular function. This is a bad idea in general and is against the design principles of angular - use ng-click instead.

    If you must mix jQuery and angular together, then make sure you do it properly by making angular aware of jQuery events so that it can trigger its digest cycle.

    You can trigger a digest in a few ways but the easiest (and most obvious as to what you code is doing) is by using $scope.$apply:

    $scope.$apply(function () {
    
      Modal.showModal({
       template : 'views/Modal.html',
       Data : aData
      });
    
    });
    

    The reason the $timeout works is because $timeout is an angular wrapper function that triggers a digest cycle as part of its implementation (it's actually very similar to $scope.$apply, but it's less obvious what it's doing / why it's needed when you review your code later, so I'd advise using $scope.$apply instead).

    Further reading: ng-book.