How to share data between controllers in Ionic?


#1

I want to know how it would be possible to share date between ionic controllers.

I have a controller where i’m retreiving a json object.

.controller('Ctlr1', function($scope, $http, $stateParams) {
$http.get("http://domain.com/view/object.json")
    .success(function (response) {
        $scope.items = response;
})

And i’m showing the items on a list using ng-repeat like the example below :

     <a class="item"  ui-sref="page2"  ng-repeat="item in items" >
   <h3>{{item.name}} </h3>
   </a>  

I have another view with another controller where I will need the id of the the item clicked !

.controller('Ctlr2', function($scope, $http, $stateParams) {
      alert(idclicked);
    })

I was thinking about using $rootScope, I’m able to share one element from a controller to another, but I don’t how to do it depending on the item clicked.

 .controller('Ctrl1', function($rootScope,$scope) {
    $rootScope.resourceId = 4;

})

.controller('Ctrl2', function($rootScope,$scope) {
     alert($rootScope.resourceId);
})

#2

You’d typically keep your shared data in a service and have each controller depend on that shared service.


#3

I’d suggest broadcast:

 .controller('Ctrl1', function($rootScope) {
    $rootScope.$broadcast('resourceChange', 4);
 })

and:

.controller('Ctrl2', function($scope) {
    $scope.$on('resourceChange', function (event, val) {
        alert(val);
    });
})

#4

Thanks for your response ! but I want to pass the Id which depends on the item clicked.


#5

Add the ng-click directive into your link

<a class="item"  ui-sref="page2"  ng-repeat="item in items" ng-click="itemSelected(item)" >

And in controller

$scope.itemSelected = function(item) {
     $rootScope.resourceId=item; //or item.id (I don't know what is hidden behind your item object)
}

#6

Thank you so much @DFull !! it works :smile:


#7

Please I have a question @DFull ! this is working only when I click on one item, if return to the home page and I click on another item it doesn’t, I should reload the page to make it work, so it works only once each page load. so how to resolve this issue ?


#8

Thanks @DFull I founded the solution I had to add cache: false, to may state in app.js


#9

you shouldn’t use $rootscope for this.
go with @encodedmirko suggestion and build a little service which just provides an array where you store your data in.


#10

Give me an example which can work on my present code.


#11

Might need to change POST in the call to GET.

.controller('Ctlr1', function($scope, $http, $stateParams, myAwesomeNewService) {
  myAwesomeNewService.call("http://domain.com/view/object.json")
    .success(function (data, status, headers, config) {
      /*
       This callback will be called asynchronously when the response is available.
       The callback was a success, get the data and sent it to the view.
       */

      // Push the new values to the template.
      $scope.items = data;
    })
    .error(function (data, status, headers, config) {
      // Called asynchronously if an error occurs or server returns response with an error status.
      console.log("request on failed");
    });
})

.service('myAwesomeNewService', function ($rootScope, $localStorage, $http, $q) {
  return {
    call: function (url) {
      var deferred = $q.defer();
      var promise = deferred.promise;

      $http({
        headers: {
          'Content-Type': 'application/x-www-form-urlencoded'
        },
        method: "POST",
        url: url
      }).success(function (data) {
        if (data) {
          deferred.resolve(data);
        }
        else {
          deferred.reject('No data available.');
        }
      }).error(function (data, status, headers, config) {
        deferred.reject(data, status);
      });

      promise.success = function (fn) {
        promise.then(fn);
        return promise;
      };
      promise.error = function (fn) {
        promise.then(null, fn);
        return promise;
      };

      return promise;
    }
  }
})

#12

You can use a service.