Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS watch not working

A watch is not working. I ng-include the following content:

<form class="search">
    <div class="searchbar">
        <input type="search" value="" data-ng-model="searchKeyword" placeholder="zoeken">
        <button type="submit"><i class="glyphicon glyphicon-search"></i></button>
    </div>
</form>

like this:

<div ng-include src="filterPath" onload="initiateSearch()"></div>

The onload function is doing this:

(function(){
    var appController = angular.module('ListerAppController', []);

    appController.controller('ListerCtrl', ['$scope', '$rootScope', '$http', '$filter', '$timeout', '$sharedFactories', 'History', '$location',
        function($scope, $rootScope, $http, $filter, $timeout, $sharedFactories, History, $location) {
            $scope.initiateSearch = function () {
            // This is what you will bind the filter to
                $scope.filterText = '';

                // Instantiate these variables outside the watch
                var tempFilterText = '',
                    filterTextTimeout;

                $scope.$watch('searchKeyword', function (val) {
                    if (filterTextTimeout) $timeout.cancel(filterTextTimeout);

                    tempFilterText = val;

                    filterTextTimeout = $timeout(function() {
                        $scope.filterText = tempFilterText;
                        $scope.pageCount = function() {
                            return Math.ceil( $scope.itemsfiltered.length / $scope.itemsPerPage );
                    };
                }, 350); // delay 250 ms
            });
        };
    }]);
})();

Everything seems to go allright but... the $watch on searchKeyword never fires the function when I start typing in the input element called searchKeyword.

like image 494
poashoas Avatar asked Oct 15 '14 17:10

poashoas


2 Answers

Have you tried adding true, as bellow?

$scope.$watch('searchKeyword', function (val) {
 /* your logic here */                    
}, true);

If you're curious about what the true is, here's the function signature from the docs:

$watch(watchExpression, listener, [objectEquality]);

When objectEquality == true, inequality of the watchExpression is determined according to the angular.equals function. To save the value of the object for later comparison, the angular.copy function is used. This therefore means that watching complex objects will have adverse memory and performance implications.

So apparently the significant thing is that it checks the equality of the old value and new value in a different way. I could see this being necessary if (correct me if I'm wrong) the value you're watching is, e.g., an array as opposed to a string.

like image 54
DevLounge Avatar answered Nov 07 '22 07:11

DevLounge


The watch has to be an attribute of the object, not the object itself, see the example here https://docs.angularjs.org/api/ng/type/$rootScope.Scope on how to add a watch, and the use of the model here https://docs.angularjs.org/api/ng/directive/input. You could try this (I have not tested it)

data-ng-model="search.keyword"

and in your controller:

$scope.search = {}

...

$scope.$watch('search.keyword', ... 
like image 36
Carl Avatar answered Nov 07 '22 06:11

Carl