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:
- AngularJS And ASP.NET MVC Movie Library Application - Part One
- AngularJS And ASP.NET MVC Movie Library Application - Part Two
- AngularJS And ASP.NET MVC Movie Library Application - Part Three- EventBinding with UI Elements
- AngularJS And ASP.NET MVC Movie Library Application - Part Four AngularJS Routing with partial templates
- AngularJS And ASP.NET MVC Movie Library Application - Integration Of IMDB Movie API - Part Five
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,
- $scope.$watch(function() {},
- function() {}
- );
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:
- $scope.$watch('searchByTitle', function (newValue, oldValue) { }
- $scope.$watch('searchByTitle', function (newValue, oldValue) { }
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:
- routingApp.controller("ApiMovieController", ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
- $scope.SearchMovieByTitle = function () {
- alert("SearchMovieByTitle called with angular scope");
- var title = $scope.searchByTitle;
- alert(title);
- $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) {
- console.log(response);
- $scope.movies = response.data.movies;
- })
- }
- $scope.dateTime = new Date().getMinutes();
- // alert('in controller');
- document.getElementById('btnSearch').addEventListener('click', callEventListenerfn);
- function callEventListenerfn(e) {
- alert("SearchMovieByTitleDigest called without angular scope");
- var title = $scope.searchByTitle;
- alert(title);
- $scope.$watch('searchByTitle', function (newValue, oldValue) {
- $scope.searchByTitle = newValue;
- console.log("$scope.searchByTitle value changed " + $scope.searchByTitle);
- // alert($scope.searchByTitle);
- });
- $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")
- .success(function (response) {
- alert($scope.searchByTitle);
- $scope.movies = response.data.movies;
- $timeout(function () {
- $scope.$digest();
- }, 100);
- })
- // });
- }
- //document.getElementById("btnSearch").addEventListener('click', function () {
- // console.log("Seach Started");
- // alert("Seach Started");
- // $scope.dateTime = new Date().getMinutes();
- // $scope.$digest();
- // });
- }]);
“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.

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.

$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.
- $timeout(function () {
- $scope.$digest();
- }, 100);

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.
- $timeout(function () {
- $scope.$digest();
- }, 100);
CodeSegment - > searchMovie.html
- <!DOCTYPE html>
- <html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- <h2>Seach Movie Using IMDB API</h2>
- <link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
- <style>
- .selected
- {
- background-color: lightyellow;
- color: red;
- font-weight: bold;
- }
- </style>
- </head>
- <body ng-app="routingApp" class="jumbotron" ng-controller="ApiMovieController">
- <div class="container">
- <!--<div ng-show="success" class="alert-success">Record has been upddated for movie : {{updatedMovie.title}}</div>
- <div ng-show="clear" class="alert-success">Record has been deleted for movie : {{updatedMovie.title}}</div>-->
- <div class="row col-md-8">
- <table class="table table-striped ">
- <tr>
- <td>
- <input type="text" ng-model="searchByTitle" class="form-control" style="width: 300px;" />
- </td>
- {{dateTime}}
- <td>
- <button type="button" ng-click="SearchMovieByTitle()" class="btn btn-info">
- Search using Angular Scope
- <span class="glyphicon glyphicon-search"></span>
- </button>
- <br />
- </td>
- </tr>
- <tr>
- <td></td>
- <td>
- <button type="button" id="btnSearch" class="btn btn-info">
- Seacrh Movie Using EventListener
- <span class="glyphicon glyphicon-search"></span>
- </button>
- </td>
- </tr>
- <tr class="thead-inverse">
- <td style="background-color: Highlight">Title</td>
- <td style="background-color: Highlight">Year of Release</td>
- <td style="background-color: Highlight">Rating</td>
- <td style="background-color: Highlight">Plot</td>
- <td style="background-color: Highlight">Actions</td>
- </tr>
- <tbody>
- <tr ng-repeat="movie in movies" ng-class="{'selected':$index == selectedRow}">
- <td>{{movie.title}}
- </td>
- <td>{{movie.year}}
- </td>
- <td>{{movie.rating}}
- </td>
- <td>{{movie.plot }}
- </td>
- <td></td>
- </tr>
- </tbody>
- </table>
- </div>
- </div>
- </body>
- </html>
- routingApp.controller("ApiMovieController", ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
- $scope.SearchMovieByTitle = function () {
- alert("SearchMovieByTitle called with angular scope");
- var title = $scope.searchByTitle;
- alert(title);
- $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) {
- console.log(response);
- $scope.movies = response.data.movies;
- })
- }
- $scope.dateTime = new Date().getMinutes();
- alert('in controller');
- document.getElementById('btnSearch').addEventListener('click', callEventListenerfn);
- function callEventListenerfn(e) {
- alert("SearchMovieByTitleDigest called without angular scope");
- var title = $scope.searchByTitle;
- alert(title);
- $scope.$watch('searchByTitle', function (newValue, oldValue) {
- $scope.searchByTitle = newValue;
- console.log("$scope.searchByTitle value changed " + $scope.searchByTitle);
- // alert($scope.searchByTitle);
- });
- $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")
- .success(function (response) {
- alert($scope.searchByTitle);
- $scope.movies = response.data.movies;
- $timeout(function () {
- $scope.$digest();
- }, 100);
- })
- // });
- }
- }]);

Vignesh ManiPosted Aug 25, 2016, 6:33 AM
Good one
Rahul SahayPosted Aug 25, 2016, 12:13 AM
Nice article!