Search code examples
angularjsangularjs-serviceangularjs-factory

Single Controller for multiple html section and data from ajax request angularjs


I'm trying to show two section of my html page with same json data, i don't want to wrap both in same controller as it is positioned in different areas. I have implemented that concept successfully by using local json data in "angular service" see the demo

<div ng-app="testApp">
<div ng-controller="nameCtrl">
    <a href="#" ng-click="addName();">Add New</a>
    <a href="#" ng-click="removeName();">Remove First</a>
    <ul id="first" class="navigation">
        <li ng-repeat="myname in mynames">{{myname.name}}</li>
    </ul>
</div>
<div>
    Lot of things in between
</div>

<ul id="second" class="popup" ng-controller="nameCtrl">
       <li ng-repeat="myname in mynames">{{myname.name}}</li>        
</ul>

JS

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


testApp.service('nameService', function($http) {
    var me = this;

    me.mynames = [
        {
            "name": "Funny1"
        },
        {
            "name": "Funny2"
        },
        {
            "name": "Funny3"
        },
        {
            "name": "Funny4"
        }
    ];

    //How to do
    /*this.getNavTools = function(){
        return $http.get('http://localhost/data/name.json').then(function(result) {
            me.mynames    = result.mynames;
            return result.data;
        });
    };*/



    this.addName = function() {
        me.mynames.push({
            "name": "New Name"
        });
    };


    this.removeName = function() {
            me.mynames.pop();
    };

});

testApp.controller('nameCtrl', function ($scope, nameService) {

    $scope.mynames        =   nameService.mynames;


    $scope.$watch(
        function(){ return nameService },

        function(newVal) {
            $scope.mynames          =  newVal.mynames;
        }
    )

    $scope.addName = function() {
        nameService.addName();
    }



    $scope.removeName = function() {
        nameService.removeName();
    }

});

jsfiddle

Next thing i want to do is to make a http request to json file and load my two section with data, and if i add or remove it should reflect in both areas.

Any pointers or exisisitng demo will be much helpful.

Thanks


Solution

  • The reason why only one ngRepeat is updating is because they are bound to two different arrays.

    How could it happen? It's because that you have called getNavTools() twice, and in each call, you have replaced mynames with a new array! Eventually, the addName() and removeName() are working on the last assigned array of mynames, so you're seeing the problem.

    I have the fix for you:

    testApp.service('nameService', function($http) {
        var me = this;
        me.mynames = []; // me.mynames should not be replaced by new result
    
        this.getNavTools = function(){
            return $http.post('/echo/json/', { data: data }).then(function(result) {
                var myname_json = JSON.parse(result.config.data.data.json);
                angular.copy(myname_json, me.mynames); // update mynames, not replace it
                return me.mynames;
            });
        };
    
        this.addName = function() {
            me.mynames.push({
                "name": "New Name"
            });
        };
    
    
        this.removeName = function() {
            me.mynames.pop();
        };
    });
    
    testApp.controller('nameCtrl', function ($scope, nameService) {
    
        // $scope.mynames        =   nameService.mynames; // remove, not needed
    
        nameService.getNavTools().then(function() {
            $scope.mynames = nameService.mynames;
        });
    
        /* Remove, not needed
        $scope.$watch(
            function(){ return nameService },
    
            function(newVal) {
                $scope.mynames          =  newVal.mynames;
            }
        );
        */
    
        $scope.addName = function() {
            nameService.addName();
        };
    
        $scope.removeName = function() {
            nameService.removeName();
        };
    });
    

    http://jsfiddle.net/z6fEf/9/