0

I have a problem with my script which collects data from database in parts. I would like to inform Angular when downloading data is finished so I used $watch. Unfortunatelly, it does not work. Angular calls function at the beginning instead of after change loadingComplete value.

angular
.module('app')
.controller('tlmController', function($scope, $http) {
    var vm              = this;
    var data            = [];
    vm.countTestLines   = 0;
    vm.loadingComplete  = false;

    $scope.$watch('vm.loadingComplete', function() {
        console.log(data);
    });     

    $http({
        method: 'GET',
        url: 'app/server/tt/count_testlines.php'
    }).then(function successCallback(response) {
        vm.countTestLines = parseInt(response.data.count);

        downloadInParts(data, 0, vm.countTestLines);

    }, function errorCallback(response) {
        console.log('error');
    });

    var downloadInParts = function(data, offset, max) {         
        if(max < offset) { 
            vm.loadingComplete = true;
            return;
        }

        $http({
            method: 'GET',
            url: 'app/server/tt/get_testlines.php',
            params: { offset: offset }
        }).then(function successCallback(response) {
            data = data.concat(response.data);          
            downloadInParts(data, offset + 5, max);
        }, function errorCallback(response) {
            console.log('error');
        });


    }

});
Mistalis
  • 17,793
  • 13
  • 73
  • 97
Michal Bialek
  • 499
  • 1
  • 10
  • 26
  • I'm not an Angular guy, but did you tried to pass newValue and oldValue to listener param into `$watch` method ? And then into it you could do check `if ( newValue !== oldValue )` and process your changes. – Belmin Bedak Dec 01 '16 at 09:22
  • If one of the answers below did solve your problem, please consider accepting one of them as answer. – Danscho Dec 07 '16 at 12:12

3 Answers3

0

The problem is that the loadingComplete is not a part of the scope. you should declare it as $scope.loadingComplete;.

Matteo Baldi
  • 5,613
  • 10
  • 39
  • 51
  • Yes, it is part of the scope as vm = this! – Danscho Dec 01 '16 at 09:30
  • as far as I know, the loadingComplete becomes a property of the controller. in order to use watch, loadingComplete should be a property of the $scope object. – asdadasfff Dec 01 '16 at 09:36
  • Not necessarily. If you are using controllerAs syntax. Take a look at this styleguide: https://github.com/johnpapa/angular-styleguide/blob/master/a1/README.md#style-y032 – Danscho Dec 01 '16 at 09:37
0

If you are using var vm = this, which is the proper way according to JohnPapa's styleguide for AngularJS, you should rewrite your $watch to:

$scope.$watch(function(){ return vm.loadingComplete }, function() {
    console.log(data);
});

Update from comments: Your function parameter data hides your data variable from your controller.

Danscho
  • 466
  • 5
  • 20
0

Since you are using 'vm' instead of '$scope', it is a necessary that you need to insert $scope.$apply in your function.

if(max < offset) { 
     vm.loadingComplete = true;
     $scope.$apply();
     return;
  }

$scope always watches for change in value and if there is any, Angular will call the $digest() function internally and the changed value will be updated. Using 'vm' wont update the value which results in your problem.