Marwen Trabelsi
Marwen Trabelsi

Reputation: 4257

Angular can't see my Array change in the view

I'm using angularjs with Node-webkit and making a desktop application with nedb(as an embedded database).

My problem is that when i load (via a service) list of object from the database and try to show them in the view (using ng-repeat), the view can't see the loaded data (looks like it is not getting any update)

When i put a static data :

$scope.levels  = [{_id:'abcd'},{_id:'efgh'}];

The view get it without any problems.

I've made some research and looks like that is somthing related to $apply and $digest...I'm not sure.

Here my code:

    //router
    .state('level', {
    url: '/level',
   templateUrl:'frontend/components/level/views/level.html',
                                                                         controller: 'LevelController'

                    })

The controller load the data from the DB asynchronously :

levelModule.controller('LevelController', function($scope,$rootScope,LevelService) {

//  $scope.levels  = [{_id:'abcd'},{_id:'eff'}];
  $scope.levels  = [];

  LevelService.getAllLevels(function(lvs) {
    console.log("tous "+JSON.stringify(lvs));
    $scope.levels = lvs;
  });

Here my service:

levelModule.factory('LevelService', function(DB_URL) {
    var Datastore = require('nedb')
    , path = require('path');
    db = {};
    db.levels = new Datastore({ filename:DB_URL+'/levels.db',autoload: true });


            return  {

                    getAllLevels : function(callback) {
                                            db.levels.find({}, function (err, lvs) {
                                                if(err)
                                                            console.log(err);
                                                        else

                                                            callback(lvs);


                                            });
                    },

                    insertLevel: function(level,callback) {
                        db.levels.insert(level, function (err, lv) {
                            if(err)
                                        console.log(err);
                                    else
                            callback(lv);
                        });
                    },
                    upsertLevel: function(level,callback) {

                        db.levels.update({_id: level._id}, {_id: level._id,price: {t1:{},t2:{},t3:{}}}, { upsert: true }, function(err,numReplaced,lv){
                                if(err)
                                        console.log(err);
                                    else
                            callback(numReplaced,lv);
                        });

           }
        };

});

And finally my view:

<table  class="table table-bordered table-hover">
     <tr ng-repeat="level in levels">
         <td>
           {{level._id}}
          </td>

         <td>
             <button ng-click="loadPrices(level)" type="button" class="btn btn-default" data-animation="am-fade-and-scale" data-template="frontend/components/level/views/level.edit.html" data-placement="center" bs-modal="modal">
                 <i class="fa fa-pencil-square-o"></i> Modifier
             </button>
         </td>
     </tr>
</table>

Any help ?

Upvotes: 0

Views: 238

Answers (2)

sheppe
sheppe

Reputation: 718

You're using an old school callback, which takes place outside of the Angular digest. It's good that you got it working by calling $apply, but you should try modifying your service to return a Promise. Promises are the Angular way of performing async operations.

You can read up more about them at https://thinkster.io/a-better-way-to-learn-angularjs/promises and https://docs.angularjs.org/api/ng/service/$q.

Upvotes: 1

Marwen Trabelsi
Marwen Trabelsi

Reputation: 4257

Solved by putting $apply() in the asynchronous function :

 LevelService.getAllLevels(function(lvs) {

    $scope.levels = lvs;
    $scope.$apply();
  });

Upvotes: 0

Related Questions