AngularJS And ASP.NET MVC Movie Library Application - $Watch And $Digest Underhood - Part Six

Hope you have had a chance to look at the last tutorial, which talks about the technology stack and creating UI HTML pages with the module and controller and Event Binding with UI elements, as well as routing in Angular JS with partial templates.

Kindly find links here as shown below:

Moving ahead in this article, we’ll try to understand about Watch and Digest, which play a vital role from an AngularJS perspective. In the last article, we have seen the integration of IMDB API, which was in Angular context.

First, we’ll try to use watch on a textbox, as shown in the image, given below:

As the name implies the $scope.watch() function, keeps watch on some variable and looks at their behavior. Whenever you register a watch, you need two functions as the parameters to the $watch() function:

Here is an example,

  1. $scope.$watch(function() {},  
  2. function() {}  
  3. );  
Value functions -> which watches the current value of the parameter and returns.

A listener function-> the listener function acts on the value that has changed and takes an adequate action to change the content of another variable or may prompt something, as per the business need.

The first function is the value function and the second function is the listener function.

The value function should return the value which is being watched. AngularJS can then check the value returned against the value, the watch function returned the last time. In this way, AngularJS can determine, if the value has changed. Here is an example:
  1. $scope.$watch('searchByTitle'function (newValue, oldValue) { }  
  2. $scope.$watch('searchByTitle'function (newValue, oldValue) { }  
This example value function watches the textbox ‘searchByTitle”. If the value of this variable changes, a different value will be returned and AngularJS will call the listener function. Later on the basis of the value, being the watch listener function, performs the written logic.

Let see this implementation practically.

I’ve written the code segment in such a way, so that we can understand an actual fact easily. Kindly find a code segment, as shown below:
  1. routingApp.controller("ApiMovieController", ['$scope''$http''$timeout'function ($scope, $http, $timeout) {  
  2.   
  3.     $scope.SearchMovieByTitle = function () {  
  4.         alert("SearchMovieByTitle called with angular scope");  
  5.         var title = $scope.searchByTitle;  
  6.         alert(title);  
  7.         $http.jsonp("http://api.myapifilms.com/imdb/idIMDB?title=" + title + "&token=5bf94c9e-203f-4a6f-91d0-a63a59a77084&format=json&language=en-us&aka=0&business=0&seasons=0&seasonYear=0&technical=0&filter=2&exactFilter=0&limit=5&forceYear=0&trailers=0&movieTrivia=0&awards=0&moviePhotos=0&movieVideos=0&actors=0&biography=0&uniqueName=0&filmography=0&bornAndDead=0&starSign=0&actorActress=0&actorTrivia=0&similarMovies=0&adultSearch=0&goofs=0"es=0&fullSize=0&companyCredits=0&callback=JSON_CALLBACK").success(function (response) {  
  8.             console.log(response);  
  9.             $scope.movies = response.data.movies;  
  10.         })  
  11.     }  
  12.   
  13.   
  14.     $scope.dateTime = new Date().getMinutes();  
  15.     // alert('in controller');  
  16.   
  17.     document.getElementById('btnSearch').addEventListener('click', callEventListenerfn);  
  18.     function callEventListenerfn(e) {  
  19.         alert("SearchMovieByTitleDigest called without angular scope");  
  20.         var title = $scope.searchByTitle;  
  21.         alert(title);  
  22.   
  23.         $scope.$watch('searchByTitle'function (newValue, oldValue) {  
  24.             $scope.searchByTitle = newValue;  
  25.             console.log("$scope.searchByTitle value changed " + $scope.searchByTitle);  
  26.             // alert($scope.searchByTitle);  
  27.         });  
  28.   
  29.         $http.jsonp("http://api.myapifilms.com/imdb/idIMDB?title=" + $scope.searchByTitle + "&token=2cr22c9e-203f-4a6f-91d0-a63a59a77084&format=json&language=en-us&aka=0&business=0&seasons=0&seasonYear=0&technical=0&filter=2&exactFilter=0&limit=5&forceYear=0&trailers=0&movieTrivia=0&awards=0&moviePhotos=0&movieVideos=0&actors=0&biography=0&uniqueName=0&filmography=0&bornAndDead=0&starSign=0&actorActress=0&actorTrivia=0&similarMovies=0&adultSearch=0&goofs=0"es=0&fullSize=0&companyCredits=0&callback=JSON_CALLBACK")  
  30.           .success(function (response) {  
  31.               alert($scope.searchByTitle);  
  32.               $scope.movies = response.data.movies;  
  33.   
  34.               $timeout(function () {  
  35.                   $scope.$digest();  
  36.               }, 100);  
  37.   
  38.           })  
  39.         // });  
  40.   
  41.     }  
  42.   
  43.     //document.getElementById("btnSearch").addEventListener('click', function () {  
  44.     //                console.log("Seach Started");  
  45.     //                alert("Seach Started");  
  46.     //                $scope.dateTime = new Date().getMinutes();  
  47.     //                $scope.$digest();  
  48.     //            });  
  49. }]);  
The code above states that the watch function is written in JavaScript eventlistener and it activates as soon as you click the “Search Movie, using EventListner”.

“searchByTitle” is ng-model defined on SeachMovie.html page, which I’ve already shared in the last tutorials. Watch function will evaluate the change made into the input type. "searchByTitle" is shown above in the diagram. This Watch() function will be effective, as soon as you click on Search Movie, using EventListener.

code

Kindly refer to the image, shown below. As soon as I search for any movie, using button Eventlistner and change any value in textBox, it starts reflecting the changes in Console Window.

console

$Scope.Digest()- > As the name implies, Digest means to convert something into absorbable substances. Thus, it works in the same way in AngularJS also. If any event doesn’t appear in Digest cycle, it has to bring into Angular Digest cycle.
  1. $timeout(function () {  
  2. $scope.$digest();  
  3. }, 100);  
$Scope.Digest()- />

JavaScript eventlistner calls, but sometimes it doesn't update the data bindings. In our case, we are hitting IMDB API, but sometimes, it doesn’t update the $scope.movies collection because the $scope.$digest() is not called after the second button's event listener is executed. To fix it, we can add a $scope.$digest() call to the last line of the button event listener or you can also put the code in $apply function also. Primarily, an objective to put the digest code into $timeout is only because of it to send this code asynchronously.
  1. $timeout(function () {  
  2. $scope.$digest();  
  3. }, 100);  
Here, is the complete code for searchMovie.html and ApiMovieController, as shown below:

CodeSegment - > searchMovie.html
  1. <!DOCTYPE html>  
  2. <html xmlns="http://www.w3.org/1999/xhtml">  
  3. <head>  
  4.   
  5.     <h2>Seach Movie Using IMDB API</h2>  
  6.     <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">  
  7.   
  8.   
  9.     <style>  
  10.         .selected  
  11.         {  
  12.             background-color: lightyellow;  
  13.             color: red;  
  14.             font-weight: bold;  
  15.         }  
  16.     </style>  
  17. </head>  
  18.   
  19. <body ng-app="routingApp" class="jumbotron" ng-controller="ApiMovieController">  
  20.     <div class="container">  
  21.   
  22.         <!--<div ng-show="success" class="alert-success">Record has been upddated for movie :  {{updatedMovie.title}}</div>  
  23.          <div ng-show="clear" class="alert-success">Record has been deleted for movie :  {{updatedMovie.title}}</div>-->  
  24.         <div class="row col-md-8">  
  25.             <table class="table table-striped ">  
  26.                 <tr>  
  27.                     <td>  
  28.                         <input type="text" ng-model="searchByTitle" class="form-control" style="width: 300px;" />  
  29.                     </td>  
  30.                     {{dateTime}}  
  31.                     <td>  
  32.                         <button type="button" ng-click="SearchMovieByTitle()" class="btn btn-info">  
  33.                             Search using Angular Scope  
  34.                             <span class="glyphicon glyphicon-search"></span>  
  35.                         </button>  
  36.                         <br />  
  37.   
  38.                     </td>  
  39.                 </tr>  
  40.                 <tr>  
  41.                     <td></td>  
  42.                     <td>  
  43.                         <button type="button" id="btnSearch" class="btn btn-info">  
  44.                             Seacrh Movie Using EventListener  
  45.                             <span class="glyphicon glyphicon-search"></span>  
  46.                         </button>  
  47.                     </td>  
  48.                 </tr>  
  49.                 <tr class="thead-inverse">  
  50.                     <td style="background-color: Highlight">Title</td>  
  51.                     <td style="background-color: Highlight">Year of Release</td>  
  52.                     <td style="background-color: Highlight">Rating</td>  
  53.                     <td style="background-color: Highlight">Plot</td>  
  54.                     <td style="background-color: Highlight">Actions</td>  
  55.                 </tr>  
  56.                 <tbody>  
  57.                     <tr ng-repeat="movie in movies" ng-class="{'selected':$index == selectedRow}">  
  58.                         <td>{{movie.title}}  
  59.                         </td>  
  60.                         <td>{{movie.year}}  
  61.                         </td>  
  62.                         <td>{{movie.rating}}  
  63.                         </td>  
  64.                         <td>{{movie.plot }}  
  65.                         </td>  
  66.                         <td></td>  
  67.                     </tr>  
  68.                 </tbody>  
  69.             </table>  
  70.         </div>  
  71.     </div>  
  72.       
  73. </body>  
  74. </html>  
Code segment for ApiMovieController is given blow:
  1. routingApp.controller("ApiMovieController", ['$scope''$http''$timeout'function ($scope, $http, $timeout) {  
  2.   
  3.     $scope.SearchMovieByTitle = function () {  
  4.         alert("SearchMovieByTitle called with angular scope");  
  5.         var title = $scope.searchByTitle;  
  6.         alert(title);  
  7.         $http.jsonp("http://api.myapifilms.com/imdb/idIMDB?title=" + title + "&token=2gr44c9e-203f-4a6f-91d0-o6121 &format=json&language=en-us&aka=0&business=0&seasons=0&seasonYear=0&technical=0&filter=2&exactFilter=0&limit=5&forceYear=0&trailers=0&movieTrivia=0&awards=0&moviePhotos=0&movieVideos=0&actors=0&biography=0&uniqueName=0&filmography=0&bornAndDead=0&starSign=0&actorActress=0&actorTrivia=0&similarMovies=0&adultSearch=0&goofs=0"es=0&fullSize=0&companyCredits=0&callback=JSON_CALLBACK").success(function (response) {  
  8.             console.log(response);  
  9.             $scope.movies = response.data.movies;  
  10.         })  
  11.     }  
  12.   
  13.   
  14.     $scope.dateTime = new Date().getMinutes();  
  15.      alert('in controller');  
  16.   
  17.     document.getElementById('btnSearch').addEventListener('click', callEventListenerfn);  
  18.     function callEventListenerfn(e) {  
  19.         alert("SearchMovieByTitleDigest called without angular scope");  
  20.         var title = $scope.searchByTitle;  
  21.         alert(title);  
  22.   
  23.         $scope.$watch('searchByTitle'function (newValue, oldValue) {  
  24.             $scope.searchByTitle = newValue;  
  25.             console.log("$scope.searchByTitle value changed " + $scope.searchByTitle);  
  26.             // alert($scope.searchByTitle);  
  27.         });  
  28.   
  29.   
  30.          
  31.         $http.jsonp("http://api.myapifilms.com/imdb/idIMDB?title=" + $scope.searchByTitle + "&token=2gr44c9e-203f-4a6f-91d0-o6121&format=json&language=en-us&aka=0&business=0&seasons=0&seasonYear=0&technical=0&filter=2&exactFilter=0&limit=5&forceYear=0&trailers=0&movieTrivia=0&awards=0&moviePhotos=0&movieVideos=0&actors=0&biography=0&uniqueName=0&filmography=0&bornAndDead=0&starSign=0&actorActress=0&actorTrivia=0&similarMovies=0&adultSearch=0&goofs=0"es=0&fullSize=0&companyCredits=0&callback=JSON_CALLBACK")  
  32.           .success(function (response) {  
  33.               alert($scope.searchByTitle);  
  34.               
  35.               $scope.movies = response.data.movies;  
  36.   
  37.               $timeout(function () {  
  38.                     $scope.$digest();  
  39.               }, 100);  
  40.   
  41.           })  
  42.         // });  
  43.   
  44.   
  45.     }  
  46.       
  47. }]);   
Hope, it’ll help you some day. Enjoy coding.