This developer's chronicles

Web development using Scrum, C#, AngularJS and the like

Category: AngularJS

Using $scope.$apply in AngularJS

In order to understand what $scope.$apply() gives us and why we would need it  is necessary to take a step back and look at they way AngularJS checks if there has been any changes to its model or its views so that it can update its bindings (and the whole process that goes behind it).

Digest cycle

In AngularJS there is a concept of digest cycle, which is pretty much a loop in which AngularJS checks for any changes to its bindings plus anything else that is being watched and lives inside its $scope (note that not everything that lives inside the $scope is being watched by Angular, only variables used in expressions such as  <div>{{message}}</div>and also when $scope.$watch is being used.)

Once a watch is fired Angular starts a new cycle ( $digest cycle) in which it checks all current variables and compare them with their previous values, if it finds any change it will then update the correspondent bindings,  if it doesn’t it will then wait until the next watch fires.

Why do I need $scope.$apply() then?

Angular only monitors variables used in expressions and anything inside of a $watch living inside the $scope. So if you are changing the model outside of the Angular context you will need then to call $scope.$apply() for those changes to be propagated, otherwise Angular will not know that they have been changed thus the binding will not be updated.

Let’s look at the below example were I’m changing the model from outside the $scope therefore any changes that I make are not visible

And this is the code in my view:

The above JavaScript code will update the model two seconds after the page has been loaded, but as this is not being watched by AngularJS (the $scope.message is but not the timeout function) no changes will be visible on the screen

So if we want the changes to be propagated we’ll need to call the $scope.$apply():

 Summary

If you are changing your model outside of your AngularJS context (or the variable that you want isn’t being watched) then you will need to use $scope.$apply in AngularJS as a way of telling it that it will need to fire a new $digest cycle so that it can detect your changes.

Understanding AngularJS $q service and promises

Update 16/07/2015: Fixed promise object not being returned thanks to Zhuinden’s comment and added plunker.

Before diving into AngularJS $q service it is essential to understand what a promise is but most importantly why we need it.

What is a promise?

A promise in the Javascript and AngularJS world is an assurance that we will get a result from an action at some point in the future, let’s see the two possible results of a promise:

  • A promise is said to be fulfilled when we get a result from that action (meaning that we get a response, regardless of whether the response is good or bad)
  • A promise is said to be rejected when we don’t get a response(for instance if we were retrieving some data from an API and for some reason we never got a response because the API endpoint was down etc.)

Why do we need promises?

We need promises because we need to make decisions based on the possible results of our call (or the possibility that we don’t get a response from that call at all), probably an example will better help describe this:

Our program contacts an external API to get the list of clients
while the response is received the program works on something else
Once the response is received (if received) the program displays the client info on the screen
If the response was not received (the API was down) then we display a message to the end user.
Here is a really good example of what promises are and it’s explained as cartoon

Using Angular’s $q service to deal with promises

Angular JS provides a service called $q which allows you to work with asynchronous functions and user their return values when the execution has been completed, and what its really cool about it is that it will let you write your custom promises as well (so you can resolve or reject a promise when appropriate).

Let’s have a look at a simple example

 

Now let’s have a look at how this would be implemented inside an AngularJS service:

 

Finally, the AngularJS controller will use the service and either display the results on the page (if the promise was fulfilled and the data received)  or will display a message indicating that there was an error when attempting to retrieve the data from github

A plunker with a copy of the code can be found here