2

I currently have an angular application which upon user login calls a service to begin a server call to refresh a count, only allowing for a server side return if the user is authenticated.

resource.approvalsCount = 0;
var approvalsCountTimer;
resource.getApprovalsCount = function (username) {
    return resource.query({
        username: username,
        q: 'approvalsCount'
    }).$then(function (response) {
        resource.approvalsCount = response.data.count;
        approvalsCountTimer = $timeout(resource.getApprovalsCount, 3000);
        return resource.approvalsCount;
    });
};

When a user logs out I am attempting to cancel that counter otherwise the server will return a 401 unauthorized error by calling a function based on the resource:

resource.cancelTimers = function () {
    $timeout.cancel(approvalsCountTimer);
}

The issue is that the counter continues to run even after I call the cancel upon the $timeout which returns a 401 from the server. Console logging out the return the cancel function returns true (cancel has worked). I have tried several different placements of the begin of the $timeout to no avail, is there a way to ensure that all of the $timeouts are canceled? I don't understand what I am missing in this configuration.

EDIT

angular.module('resources.approvals.approvals', ['ngResource'])
    .factory('Approvals', ['$timeout', '$resource', function ($timeout, $resource) {
    var resource = $resource('/approvals/:username/:requestID', {}, {
        'update': {
            method: 'PUT'
        }
    });
    resource.approvalsCount = 0;
    var approvalsCountTimer;
    resource.getApprovalsCount = function (username) {
        return resource.query({
            username: username,
            q: 'approvalsCount'
        }).$then(function (response) {
            resource.approvalsCount = response.data.count;
            approvalsCountTimer = $timeout(resource.getApprovalsCount, 3000);
            return resource.approvalsCount;
        });
    };
    resource.cancelTimers = function () {
        $timeout.cancel(approvalsCountTimer);
    };
    return resource;
}]);
7
  • How did you call cancelTimers in your code? Commented Aug 8, 2013 at 18:18
  • I call it within the logout process, so on my main menu controller i have a $scope.logout = function(){ Resource.cancelTimers(); } Commented Aug 8, 2013 at 18:22
  • Is approvalsCountTimer defined in the closure of resource object? Can you post the entire resource code? Commented Aug 8, 2013 at 18:25
  • Added code changes above. Commented Aug 8, 2013 at 18:30
  • you are actually recursively calling getApprovalsCount in the timeout, is that what you really need? Commented Aug 8, 2013 at 18:41

1 Answer 1

1

I think your code looks good. It got to be something else.

I simplified a bit and you can see it on the demo. it simulates the http call every half second and the cancelTimes will be called in 4 seconds.

app = angular.module('app', []);
app.factory('Approvals', ['$timeout', function ($timeout) {
    var resource = {};
    resource.approvalsCount = 0;
    var approvalsCountTimer;
    resource.getApprovalsCount = function (username) {
        console.log(approvalsCountTimer);
        approvalsCountTimer = $timeout(resource.getApprovalsCount, 500);
    };
    resource.cancelTimers = function () {
        console.log("stopped");
        $timeout.cancel(approvalsCountTimer);
    };
    return resource;
}]);

function Ctrl($scope, $timeout, Approvals) {
    Approvals.getApprovalsCount();
    $timeout(Approvals.cancelTimers, 4000)
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.