0

Background:

I am building my offline application which uses AngularJS for UI and PocuhDB for locally storing the data retrieved from the server.

Issue:

The data retrieved from PouchDB is not getting rendered in the UI.

Controller:

$scope.retrieveView = function (sys, code, majorVer, minorVer) {
    var promise;
    promise = dataService.getDataFromLocalDb().then( 
       function(dataFromPouchDb){            
        $scope.data = dataFromPouchDb.data;
    });

    return promise;
  }

And then in the UI code I have the following :

<h1> {{data}}</h1>

I have debugged the code and everything seem to work fine. But the data is not getting displayed in the UI.

If I hard code a value to the data field then its getting rendered in the UI

$scope.data ="TEST";
user1455719
  • 1,045
  • 4
  • 15
  • 35
  • It looks like you aren't closing the `( )` for your then call. – dting Mar 28 '15 at 01:57
  • DTing, the code shown is not the real code..I have used it to just explain the issue. Anyway , i have modified the code. – user1455719 Mar 28 '15 at 03:36
  • The code started to work when i added the following : if(!$scope.$$phase) { $scope.$digest(); } . But i have no idea what magic does this code do. It would be a great help if some some could advice. – user1455719 Mar 28 '15 at 04:24

3 Answers3

1

This question is kind a old but I just came around it.

Issue is that Angularjs is based on so called digest cycles. When your model or view is changed digest cycle is triggered, watch for changes and update model or view respectively. It is so called two way data binding.

This digest cycle is not triggered periodically on some time base but on events instead. Those events are angular directives like ng-click, ajax calls $http or some other angular events like $timeout. You can find more information about digest here.

In general you should use those things when working with angular application to avoid such situations. In some cases its not possible however like in your case when getting data from DB. Digest cycle is not triggered and your view is not updated by angular.

Workaround for this is manually trigger $digest cycle. Way you have described:

if(!$scope.$$phase) { 
   $scope.$digest(); 
} 

is working but considered as angular anti-patern and is discouraged by angular team, you should use:

$timeout();

instead. For more information see this answer.

I would maybe consider adding $timeout() call to hook for insert, update, delete hooks or events. Maybe pouchDB sync could be helpfull there.

Community
  • 1
  • 1
Mior
  • 821
  • 8
  • 16
0

The code you show seemed correct, maybe you can use console.log() to track the progress of the data. I think the problem might not in this layer. Maybe in the area where you wrapped getDataFromLocalDb(), track and find if the data have transfer to here, or where it disappeared.

michaelpri
  • 3,521
  • 4
  • 30
  • 46
GGOD
  • 1
  • It is definitely picking the data from the pouchDB. I have debugged the code and seen the data coming. But for some reason the retrieved data when set to the Angularjs scope field is not getting reflected in the UI. – user1455719 Mar 28 '15 at 03:23
  • The code started to work when i added the following : if(!$scope.$$phase) { $scope.$digest(); } . But i have no idea what magic does this code do. It would be a great help if some some could advice. – user1455719 Mar 28 '15 at 04:22
  • I have searched something, that "`$$phase` is a flag set while angular is in a `$digest` cycle.", and `$scope.$digest();` call the $digest cycle.I think it's because that the data in js have already changed but didn't in the UI. So it should call `$digest` cycle to check the change of the data-binding. – GGOD Mar 28 '15 at 05:42
0

The code started to work when i added the following :

if(!$scope.$$phase) { 
    $scope.$digest(); 
} 

But i have no idea what magic does this code do.
It would be a great help if some some could advice.

The complete code that works now is :

$scope.retrieveView = function (sys, code, majorVer, minorVer) {
        var promise;
        promise = dataService.getDataFromLocalDb().then( 
           function(dataFromPouchDb){            
            $scope.data = dataFromPouchDb.data;
    if(!$scope.$$phase) { 
        $scope.$digest(); 
    } 

        });

  return promise;
}
user1455719
  • 1,045
  • 4
  • 15
  • 35