Chris
Chris

Reputation: 27394

Why is $timeout is needed for watch to trigger

I have a directive that watches the height of an element. That element is updated by a controller that uses a factory method to get data. Unless I have a $timeout in that factory my watch never gets updated. Curious! Can anyone shed light onto why?

My controller:

$scope.update = function () {
    apiService.getLinks(function (response) {
        $scope.links = response;
        // If I try $scope.$apply() here it says its already in progress, as you'd expect
    });
}

quickLinksServices.factory('quickLinksAPIService', function ($http, $timeout) {

    quickLinksAPI.getQuickLinks = function (success) {

        //without this the watch in the directive doesnt get triggered
        $timeout(function () { }, 100); 

        $http({
            method: 'JSON',
            url: '/devices/getquicklinkcounts'
        }).success(function (response) {
            quickLinksAPI.quicklinks = response;
            quickLinksAPI.saveQuickLinks();

            success(response);
        });
    }

The directive I'm using is here

Upvotes: 2

Views: 359

Answers (2)

Manuel B.
Manuel B.

Reputation: 115

This is because you are not working with the $http promise in the right way.

Following code is not tested, but shows how you could solve your problem. Note the return $http. Here you return the promise and handle the promise in your code.

$scope.update = function () {
  quickLinksServices.quickLinksAPI.getQuickLinks().then(function(data){
        $scope.links = data;
     }
    );
 };


quickLinksServices.factory('quickLinksAPIService', function ($http, $timeout) {
    quickLinksAPI.getQuickLinks = function (success) { return $http({
        method: 'JSON',
        url: '/devices/getquicklinkcounts'
    });
    });
}

If you can't make it work this way because of design decisions, you still have to work with promises ($q). If you want to know more about promises here is a good thread on stackoverflow.

Upvotes: 0

Sudarshan Kalebere
Sudarshan Kalebere

Reputation: 3937

Basically angularjs provides $timeout service to trigger function call after specified time, but as I know the use of $timeout is not strictly needed, basically people have habit of writing this I mean they need to trigger watch after specified interval. but in many cases $apply does the trick. The thing you need is $apply(). for your reference please check this

Also many times what happens is angulars $watch executes very faster than you expected so it may send incomplete updates or response In such cases $timeout plays the important role by delaying $watch. You can clear $timeout if $watch is fast enough to your need, which means $timeout is the way to explicitly trigger the $watch, where as $apply can do it by itself. So the use of $timeout or $apply is depends on how your requirement is. Hope this clears you. Good luck.

Upvotes: 3

Related Questions