How to update $scope with every loop of a $timeout with angular

I have a function that runs in the background and takes a long time and I want to update the user of my webpage about progress as it’s going. I have a bit of angular that asks the results/[jobID] page what the progress is and that successfully returns the progress.

It runs every 2 seconds and the $log.log(data,status) works, so I see “10%”, “30%” etc in the logs, but my {{progress}} variable on the page only updates when the job is complete (ie. triggers the else if (status === 200) loop).

How can I get the $scope.progress to update {{progress}} on every run of poller()?

function getProgress(jobID) {

    var timeout = '';

    var poller = function() {
        $http.get('/results/'+jobID).
        success(function(data,status,headers,config) {
            if(status === 202) { // This logs, but doesn't change {{progress}}
                $log.log(data, status);
                $scope.progress = data;
            } else if (status === 200) { // This logs and changes {{progress}}
                $log.log(data);
                $scope.progress = data;
                $timeout.cancel(timeout);
                return false;
            }
            // continue to call the poller() function every 2 seconds
            // until the timeout is cancelled
            timeout = $timeout(poller,2000);
        }).
        error(function(error) {
            $log.log(error);
        });
    };
    poller();
}

getProgress(1234) //is called by another function on form submit

If relevant I’m using flask & python code to make the actual pages

Answer

Thanks to Faustyn Piechowiak, working answer here:

Interestingly this runs both parts of the try/catch, so will also log “didn’t apply”, but it does what I wanted so I’m happy.

function getProgress(jobID) {
    var timeout = '';
    var poller = function() {
        $http.get('/results/'+jobID).
        success(function(data,status,headers,config) {
            if(status === 202) { // This logs, but doesn't change {{progress}}
                $log.log(data, status);
                $scope.progress = data;
                $scope.comment = data;
                try { // This updates the scope
                    $scope.apply();
                }
                catch(err) { // This also runs
                    $log.log("didn't apply")
                }

            } else if (status === 200) { // This logs, and changes {{progress}}
                $log.log(data);
                $scope.progress = data;
                $timeout.cancel(timeout);
                return false;
            }
            // continue to call the poller() function every 2 seconds
            // until the timeout is cancelled
            timeout = $timeout(poller,2000, true);
        }).
        error(function(error) {
            $log.log(error);
        });
    };
    poller();
}

getProgress(1234) //is called by another function on form submit

Leave a Reply

Your email address will not be published. Required fields are marked *