Share async data between controllers without making multiple requests
angularjs, angularjs-scope, angularjs-service
Solution
Since you are using a promise, to access the data returned by promise use the callback syntax
function appInstallerDetailCtrl($scope, $routeParams, Data) {
$scope.appId = $routeParams.appId;
Data.then(function(returnedData) {
$scope.apps=returnedData;
console.log($scope.apps);
for (var i in $scope.apps)
console.log(i)
});
}
Make sure this
defer.resolve(result.data.versions.version);
resolve returns array, for the above code to work. Or else see what is there in data and ajust the controller code.
Problem
I'm trying to make a single `$http` request to get one of my JSON files and use the data across all my controllers. I saw on egghead.io how to share data across multiple controllers, and I've also read this StackOverflow question: "Sharing a variable between controllers in angular.js". However, the answers there don't use the `$http` module. When using `$http`, the controllers don't have the data to work on, and by the time the response is received it's already too late. I then found the method `$q.defer` and this question on StackOverflow: "AngularJS share asynchronous service data between controllers" The solution posted there works fine, BUT it has two issues: - Each controller will trigger the `$http` request to obtain the same data already used in another controller; and, - If I try to manipulate the data received I have a `then` function. Below you can see my code: controllers.js ``` 'use strict'; /* Controllers */ function appInstallerListCtrl($scope, Data) { $scope.apps = Data; } function appInstallerDetailCtrl($scope, $routeParams, Data) { $scope.appId = $routeParams.appId; $scope.apps = Data; console.log($scope.apps); // <-- then function console.log(Data); // <-- then function with $vv data returned but I can't access it for (var i in $scope.apps) // <--- no way, baby! console.log(i); } ``` app.js ``` var app = angular.module('appInstaller', []); app.factory('Data', function($http, $q) { var defer = $q.defer(); $http.get('apps.json').then(function(result) { defer.resolve(result.data.versions.version); }); return defer.promise; }); app.config(['$routeProvider', function($routeProvider) { $routeProvider. when('/app', {templateUrl: 'partials/app-list.html', controller: appInstallerListCtrl}). when('/app/:appId', {templateUrl: 'partials/app-detail.html', controller: appInstallerDetailCtrl}). otherwise({redirectTo: '/app'}); }]); ``` What I'd like to have is that when launching the app, the `$http` request will be performed and the response will be used throughout the app across all controllers. Thanks