0

I have the following model:

 var MODEL = { myTable: [], anotherTable: [] }; //--- initially set as empty arrays

MODEL is a global variable as it is used to bind the app model in different controllers.

I have devined a service that updates the model, getting the data from a php page that returns the table rows:

myApp.factory('myAppUtils', function($http) {
     return {
            updateModelTable: function(tableName) {
                var pageToCall = "";
                var params = "";
                switch(tableName){
                    case 'myTable':
                        pageToCall = "myTable.php";
                        params = "";
                        break;
                    case 'anotherTable':
                        break;
                    default:
                        break;
                }

                var updateModel = function(tableName, data){
                    MODEL[tableName] = data;
                };

                var url = "/" + pageToCall;
                $http.get(url).
                    success(function(data, status, headers, config) {
                        updateModel(tableName, data);
                    }).
                    error(function(data, status, headers, config) {
                        alert("error");
                    });
            }
        };
});

and then one of the controllers:

myApp.controller("MyTableCtrl", function($scope, myAppUtils){
    $scope.table = MODEL.myTable;
    myAppUtils.updateModelTable("playersTable");
});

once I run the app, the myAppUtils.updateModelTable() function is correctly invoked, it does update successfully the MODEL but the view controlled by MyTableCtrl does not update accordingly.

What I'm trying to do is to set up some sort of CRUD operations, getting and setting values from a sql db. I'd like to, for example, insert a new record and then call the update function to update the model and consequently the view, but this is not happening.

Is this the correct "angular" way to do the thing?

Any hint? What am I doing wrong?

Thanks in advance

BeNdErR
  • 17,471
  • 21
  • 72
  • 103
  • how about bind `$scope.model` to `MODEL` then access `{{model.myTable}}` in your view ? – Rebornix Jun 04 '15 at 12:02
  • It looks like you are first assigning `$scope.table` to equal `MODEL.myTable` (which is an empty array, at time of assignment), then you are updating the table, where you are replacing the empty array with an object in `MODEL`. `$scope.table` is still equal to the empty array, though. – Claies Jun 04 '15 at 12:03
  • is there any specific reason that you must have a global variable holding all your table values? generally speaking, this is a bit of an anti-pattern. – Claies Jun 04 '15 at 12:05
  • @Claies I'm learning angular, so probably I'm making mistakes. How would you suggest to proceed? I'd like to share the same model between different views. I thought the global variable was a good way to do that – BeNdErR Jun 04 '15 at 12:07
  • 1. Put MODEL to $rootScope. 2. Service should just return value. – Petr Averyanov Jun 04 '15 at 12:07
  • @BeNdErR you can use a service as storage as it's singleton. – Rebornix Jun 04 '15 at 12:07
  • @Rebornix the view is correctly bound to the model. If I initialize MODEL.myTable with something, the view shows it correctly. Once I update the MODEL via $http instead the view is not updated accordingly – BeNdErR Jun 04 '15 at 12:07
  • 2
    @BeNdErR just like Claies, hold a global variable in your code is not a good idea, a better solution is to create a service to share data between controllers, see my answer below. Besides, you can refer to http://stackoverflow.com/questions/30507754/angular-js-api-using-a-factory/30507914#30507914 for more samples. – Rebornix Jun 04 '15 at 12:17

1 Answers1

1

Instead of using a global variable to share data between controllers, you can use a separate service to cache data, as Angular Service is singleton.

So in your case, create a service

myApp.service('modelService',function() {
    var model = {
      myTable: [],
      anotherTable: []
    };

    return model;
});

Then in your factory, inject this service and change your updateModel to

var updateModel = function(tableName, data){
    modelService.myTable = data;
};

And in your controller, inject modelService and bind it to $scope as

$scope.model = modelService;

Finally, in your view, you can access model.myTable, which can be updated automatically once you update them in your factory.

Rebornix
  • 5,272
  • 1
  • 23
  • 26
  • @Rebornix Yeah, finaly someone who know how to do it right. In addition you can read my answer to this thread http://stackoverflow.com/questions/30508773/ngrepeat-not-updating-after-model-changed/30510369#30510369 that provide some information about a common issue with bindings into a factory/service with a controller. – Okazari Jun 04 '15 at 15:18