How to use the setTimeout with angular

I have the code:

if (xxx == xxx){
    var x = 5 + 3;
    setTimeout(function() { 
        $('.regErrMsg').text("");
        $scope.errMsg = "Hi.";
    }, 5000);
}

I would like to execute the function i.e, show "Hi" message after 5 seconds. So, is my code correct. As of now, the message is not showing up. Where have I gone wrong?

The "problem" with setTimeout inside your controller is that angular is not going to watch the content of the scope after the function in the setTimeout is called.

Solution 1

You can do $scope.$apply() to force the view to update, eg:

setTimeout(function() { 
    $scope.errMsg = "Hi.";
    $scope.$apply();
}, 5000);

Solution 2

They is a special function $timeout which will trigger the view refresh automatically after the function has been called. It has the same signature as setTimeout.

$timeout(function() { 
    $scope.errMsg = "Hi.";
    //You don't need $scope.$apply() here
}, 5000);

You should inject $timeout into your controller

I have removed the $('.regErrMsg').text(""); because you shouldn't change the dom inside a controller.

My question is .. does the Hi executes and then it waits for 5 sec or wait waits for 5 secs and then shows Hi ?

Let's consider a simplified example

foo();
setTimeout(function () {bar();}, 5000);
baz();

Now it's easier to describe what will happen, step by step (in excruciating detail)

  1. Line 1: foo gets interpreted
  2. () invokes foo
  3. Line 2: setTimeout gets interpreted
  4. The arguments to be passed into setTimeout are interpreted, i.e. function references set here
  5. The (/* ... */) invokes setTimeout
  6. setTimeout sets up a callback to invoke argument 0 after argument 1 milliseconds
  7. Line 3: baz gets interpreted
  8. () invokes baz
  9. End of file ...nothing happens for a while...
  10. argument 0 (from 5) gets invoked
  11. bar gets interpreted (using references from 4)
  12. () invokes bar

As of now, the message is not showing up. Where have I gone wrong?

It looks like the only change you've made that will be reflected in the DOM is the clearing of text from .regErrMsg, perhaps you meant to use

$('.regErrMsg').text("Hi.");

or invoke some other method which will make the updated vale of $scope be reflected in the #document