R.Bar
R.Bar

Reputation: 362

Sharing data between controllers - Angularjs

i have a problem while im trying to share a data between two controllers. Here is my code :

<html>
<head>
    <title>My Angular App</title>
</head>
<body ng-app="MyTest">

<div ng-controller="ViewController as vmView">
    <ul>
        <li ng-repeat="singleItem in vmView.allData">
            {{ singleItem }}
        </li>
    </ul>

    {{ vmView.checkItOut }}

    <input type="button" ng-click="vmView.justClick()" />
</div>

<div ng-controller="AddController as vmAdd">
    <form ng-submit="vmAdd.saveChanges()">
        <input type="text" ng-model="vmAdd.inputText" />
        <input type="submit" />
    </form>
</div>

<script src="angular.js"></script>
<script src="app.js"></script>
<script type="application/javascript">
    angular.module('MyTest')
            .factory('shareDataFactory', function($http, $q) {
                var data = {};

                data.list = $q.defer();

                data.getAllData = function() {
                    $http.get('http://www.w3schools.com/angular/customers.php')
                            .then(function(response) {
                                data.list = $q.resolve(response.data.records);
                            });

                    return data.list.promise;
                };

                data.addData = function(newData) {
                    data.list.push(newData);
                };

                return data;
            });

    angular.module('MyTest')
            .controller('ViewController', function ViewController(shareDataFactory) {
                var vm = this;

                vm.allData = shareDataFactory.getAllData();

                vm.checkItOut = "Just checking ..";

                vm.justClick = function() {
                    console.log(vm.allData);
                }
            });

    angular.module('MyTest')
            .controller('AddController', function AddController(shareDataFactory) {
                var vm = this;

                vm.inputText = "Hello";

                vm.saveChanges = function() {
                    shareDataFactory.addData(vm.inputText);

                    // Clear the data
                    vm.inputText = "";
                };
            });
</script>
</body>
</html>

vm.allData its just not updating affter the request come back from the server. i tried to solve this for a long time but without success. thanks you everyone and have a lovely week, rotem

Upvotes: 1

Views: 331

Answers (2)

Marc Nuri
Marc Nuri

Reputation: 3614

Here you can find a working version of your code. When data is loaded, you are replacing the bound list with a new one, so changes aren't getting reflected anymore.

Html

<div ng-controller="ViewController as vmView">
    <ul>
        <li ng-repeat="singleItem in vmView.allData">
            {{ singleItem }}
        </li>
    </ul>

    {{ vmView.checkItOut }}

    <input type="button" ng-click="vmView.justClick()" />
</div>

<div ng-controller="AddController as vmAdd">
    <form ng-submit="vmAdd.saveChanges()">
        <input type="text" ng-model="vmAdd.inputText" />
        <input type="submit" />
    </form>
</div>

</body>

Javascript

 var module = angular.module('MyTest', []);

 module.service('shareDataFactory', function($http, $q) {
   var data = {
     list: []
   };
   $http.get('http://www.w3schools.com/angular/customers.php')
     .then(function(response) {
       Array.prototype.push.apply(data.list, response.data.records);
     });


   return {
     getData: function() {
       return data;
     },
     addData: function(newData) {
       data.list.push(newData);
     }

   };
 });


 module.controller('ViewController', function ViewController($scope, shareDataFactory) {


   $scope.allData = shareDataFactory.getData().list;
   $scope.checkItOut = "Just checking ..";

   $scope.justClick = function() {
     console.log($scope.allData);
   }
 });

 module.controller('AddController', function AddController($scope, shareDataFactory) {


   $scope.inputText = "Hello";

   $scope.saveChanges = function() {
     shareDataFactory.addData($scope.inputText);

     // Clear the data
     $scope.inputText = "";
   };
 });

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691635

Your code doesn't make much sense:

data.list = $q.defer();

So, data.list is a deferred object. But later

data.list = $q.resolve(response.data.records);

Ah, it's not a deferred anymore: it's being replaced by a resolved promise, unrelated to the promise returned by getAllData(). But later

data.list.push(newData);

Ah, that code thinks it's an array, and not a promise not a deferred.

That can't be right. If you want to be able to push, it must be an array. If you want to populate the array when the http promise is resolved, then push to this aray

It's also unclear what the service should do: it gets data from an HTTP service, but doesn't send the new values to that HTTP service. So, every time you'll call getAllData(), you'll lose the added values.

Anyway:

            var list = [];
            var getAllData = function() {
                $http.get('http://www.w3schools.com/angular/customers.php')
                        .then(function(response) {
                            // clear the array
                            list.splice(0, list.length);
                            // copy every record to the array
                            response.data.records.forEach(function(record) {
                                list.push(record);
                            });
                        });

                return list;
            };

            var addData = function(newData) {
                list.push(newData);
            };

            return {
                getAllData: getAllData,
                addData: addData
            };

Upvotes: 1

Related Questions