Can we update $timeout in AngularJS?

145 Views Asked by At

Following is what I'm trying to do. When the first timeout is forcibly cancelled, I want to initiate the second timeout function, without the lag that already exists, had the timeout not been cancelled.

$scope.data1_timeout = $timeout(function() {
  // some action
}, 2000);

$scope.data2_timeout = $timeout(function() {
  // some action
}, 4000);

$scope.show = function() {
  if (some action) {
    $timeout.cancel($scope.data1_timeout); //works perfectly fine
    //But how do I update data2_timeout so that the action inside it occurs just after data1_timeout is cancelled in this block.
  }
}

2

There are 2 best solutions below

11
On BEST ANSWER

Easy doing by cancel both $timeout's and call your function manually. Keep it simple =).

$scope.data1_timeout = $timeout(function() {
  // some action
}, 2000);

$scope.data2_timeout = $timeout(function() {
  myAction();
}, 4000);

$scope.show = function() {
  if (some action) {
    $timeout.cancel($scope.data1_timeout);
    $timeout.cancel($scope.data2_timeout);
    myAction();
  }
}

function myAction () {
  console.log('done');
}
0
On

This uses the promise returned by $timeout which gets rejected when the $timeout is canceled. The catch handler rejects the second timer and performs its actions immediately.

$scope.data1_timeout = $timeout(function() {
  // some action
}, 2000);

$scope.data2_timeout = $timeout(function() {
  // some action
}, 4000);

$scope.data1_timeout.catch(function(){
    $timeout.cancel($scope.data2_timeout);
    //same actions here as in data2_timeout
})

It'd make more sense to encapsulate the data2_timeout functionality in a named function and call it from both places like so:

$scope.data1_timeout = $timeout(function() {
  // some action
}, 2000);

function someAction2() {
    //some action
}

$scope.data2_timeout = $timeout(someAction2, 4000);

$scope.data1_timeout.catch(function(){
    $timeout.cancel($scope.data2_timeout);
    someAction2();
})

Note: If the intent is for data2 actions to wait for data1_timeout to complete or be canceled, then instead of data2 being a timeout, just add it as a .finally() callback for the data1_timeout promise.

$scope.data1_timeout = $timeout(function() {
  // some action
}, 2000);

$scope.data1_timeout.finally(function() {
  // do data2 stuff here.
  // Guaranteed to run, after data1_timeout completes or is canceled.
});