2

I got stuck , can any one please help me. Here are codes. I am writing grabData service to get data from url. Then in the controller firstcontroller I am filtering data according to search box: This is the code:

.factory("grabData",['$http',function($http){
    return{
        showData:function(){
            return $http.get("/http://localhost:5555/sampleData.json");
        }
    }
}])
.controller('firstController',function($scope, $filter,grabData) {
         grabData.showData().success(function(data){
         $scope.items = data;
         $scope.items1 = $scope.items;

         $scope.$watch('search', function(val){
              $scope.items = $filter('filter')($scope.items1, val);
         });
}

And HTML code is: <div ng-controller="firstController"> <input type="text" ng-model="search"> </div>

Can any one please help me in displaying $scope.items in next controllers:

.controller('secondcontroller',function($scope){
   // Here I want to use $scope.items , from first controller
})
.controller('thirdcontroller',function($scope){
   // Here I want to use $scope.items , from first controller
})
.controller('fourthcontroller',function($scope){
   // Here I want to use $scope.items , from first controller
})

Can any one please help to solve this problem.

naik3
  • 319
  • 2
  • 8
  • 22
  • 1
    Cache the data in the service and reference it if it already exists. Force a refresh if needed otherwise. [Something like this](http://stackoverflow.com/questions/19648345/angularjs-factory-only-called-once). Then inject the service into your controllers as needed. – mariocatch May 16 '16 at 16:40

2 Answers2

3

Write your service like this,

.service("grabData",['$http', '$q', function($http, $q){

    var sampleData = null;
    var filteredData = null;

    this.showData = function () {
        var deferred = $q.defer();

        if(sampleData!=null){  
           //if data has already been fetched from server before, serve it
            deferred.resolve(sampleData)
        } 
        else {   
            //else, fetch the data from server, and store it for future use
            $http.get("/http://localhost:5555/sampleData.json").then(function(res){
              sampleData = res.data;
              deferred.resolve(sampleData);
            })
        }
        return deferred.promise;
     };

     //call this from controller1, inside your watch
     this.setFilteredData = function(data){
        filteredData = data;
     };

     //call this from other 2 controllers
     this.getFilteredData = function(){
       return filteredData;
     };


    }])

And then modify your controllers like this,

.controller('secondcontroller',function($scope, grabData){
   // do whatever you want to do with grabData
   //use that "grabData.showData().success" pattern as it is still a promise
})
.controller('thirdcontroller',function($scope, grabData){
   // do whatever you want to do with grabData
   // call grabData.getFilteredData() from here
})
.controller('fourthcontroller',function($scope, grabData){
   // do whatever you want to do with grabData
   // call grabData.getFilteredData() from here
})

Hope it helps. If any doubt, please ask in comments.

Suman Barick
  • 3,311
  • 2
  • 19
  • 31
  • Thank you reply.. I am doing filtering , in the **firstcontroller**. I want to use that filtered data from **firstcontroller** in my remainging controllers. – naik3 May 17 '16 at 02:39
  • can I write filtering code in the grabData service only. If that is the case , how can I take filtering input from HTML and pass it to **grabData** service for filtering. – naik3 May 17 '16 at 02:43
  • In your `grabData` service, write 2 functions, `setFilteredData(data)` and `getFilteredData()` . call `setFilteredData` from 1st controller and `getFilteredData` from the other 2. This will do the job. Since everything is happening inside Angular world, any change in one part will automatically trigger change in all other part. – Suman Barick May 17 '16 at 04:16
  • you are Welcome :) – Suman Barick May 17 '16 at 06:48
  • Hi.. I tried the above mentioned code. It is giving error "**grabData.setFilterData is not a function**" can you please help me. – naik3 May 17 '16 at 09:09
  • Did you inject grabData in your controller? is it **setFilterData** or **setFilteredData** ... Check for spelling mistakes, because it should work. Or, if possible can you make a fiddle or plunkr? It will be helpful for me to debug if I can see the code :) – Suman Barick May 17 '16 at 09:31
  • Hi.. herer is the [link](https://plnkr.co/edit/Lz1uaBubjmbHONbZ3M1E?p=catalogue) to plunker. – naik3 May 17 '16 at 09:55
  • I have fixed a lot of issues. But I need the code for filter to proceed. Can you plz provide the code for filter? https://plnkr.co/edit/3Enmxq9hLZX49g8oaVii?p=preview – Suman Barick May 17 '16 at 10:37
  • Hi... Thanks for corrections... Filter code.. ?Filter code is written in **firstcontroller** . U want json data...?? – naik3 May 17 '16 at 10:48
  • I think this question / answer / comment has gone way to out of scope. If you need help in writing / configuring your filter, it will be better if you start ask a new question. And close it marking this answer as selected @naik3 – Suman Barick May 17 '16 at 10:49
  • @naik3 ok, let me have a look again – Suman Barick May 17 '16 at 10:50
  • No, not that one, you need to define your filter like `angular.module('app', []).filter('yourFilterName', function(){})` this syntax. Angular does not provide a "unique" filter by default. But AngularUI does. Check this answer for details http://stackoverflow.com/questions/15914658/how-to-make-ng-repeat-filter-out-duplicate-results – Suman Barick May 17 '16 at 10:55
  • Actually with respect to [this](http://jsfiddle.net/Onza/cWVrV/) I have developed my code. Filtering option is working fine. I have checked it with console.log. Only this calling to service function is giving problem. – naik3 May 17 '16 at 11:17
-1

You need to inject the factory:

.controller('firstController', ['grabData', function($scope, $filter,grabData) {
  // Your code here
}]);

The same goes for your other controllers.

rrd
  • 5,789
  • 3
  • 28
  • 36
  • What if showData() is an expensive server call? Are you going to call it multiple times, for each controller? – user1620220 May 16 '16 at 15:52
  • Well if that is the case it might be more prudent for him to use ui-router, put the call in a resolve in the parent state then let the child states have controllers. Then each can access the parent's resolve, which holds the single call to showData(). – rrd May 16 '16 at 15:53
  • If same code goes in all controller means , Do I have to write HTML code for corresponding HTML , div tags ..???? – naik3 May 16 '16 at 15:59
  • @naik3 It depends what you're trying to do ultimately. Why have separate controllers, for example? If they're all on the same page, then you only really need one controller. If they're spread across several pages, and several $states/views (like when you use [ui-router](https://angular-ui.github.io/ui-router/site/#/api/ui.router)) then you might want to do what I suggested in comment above and have the one single service call in a resolve. I'll put all this in an edit when I'm not at work, to make it a bit clearer. – rrd May 16 '16 at 16:22