title: Sharing async model data between controllers
body: <p>WARNING: fairly long question</p>
  
  <p>I am new to angular and I've gone through a few tutorials and examples such as the <a href="http://docs.angularjs.org/tutorial" rel="nofollow">official tutorial</a> on the angularjs website. The recommended way to get data into your app and share that data between controllers seems very clear. You create a service that is shared by all controllers which makes an asynchronous request to the server for the data in JSON format.</p>
  
  <p>This is great in theory, and seems fine in the extremely simple examples that only show one controller, or when controllers don't share logic that depends on the shared data. Take the following example of a simple budget application based on yearly income and taxes:</p>
  
  <p>Create the app with a dependency on <code>ngResource</code>:</p>
  
  <pre><code>var app = angular.module('budgetApp', ['ngResource']);
  </code></pre>
  
  <p><strong>NetIncomeCtrl</strong> controller that handles income and tax items, and calculates net income:</p>
  
  <pre><code>app.controller('NetIncomeCtrl', function ($scope, BudgetData) {
      var categoryTotal = function (category) {
          var total = 0;
          angular.forEach(category.transactions, function (transaction) {
              total += transaction.amount;
          });
          return total;
      };
  
      $scope.model = BudgetData.get(function (model) {
          $scope.totalIncome = categoryTotal(model.income);
          $scope.totalTaxes = categoryTotal(model.taxes);
      });
  
      $scope.netIncome = function () {
          return $scope.totalIncome - $scope.totalTaxes;
      };
  });
  </code></pre>
  
  <p><strong>BudgetData</strong> service that uses <code>$resource</code> to retrieve the JSON data from the server:</p>
  
  <pre><code>app.factory('BudgetData', function ($resource) {
      return $resource('data/budget.json');
  });
  </code></pre>
  
  <p><strong>budget.json</strong> contains the JSON data returned from the server:</p>
  
  <pre><code>{
      "income": {
          "transactions": [
              {
                  "description": "Employment",
                  "amount": 45000
              },
              {
                  "description": "Investments",
                  "amount": 5000
              }
          ]
      }, 
      "taxes": {
          "transactions": [
              {
                  "description": "State",
                  "amount": 5000
              },
              {
                  "description": "Federal",
                  "amount": 10000
              }
          ]
      },
  }
  </code></pre>
  
  <p>Then on my screen I have two repeaters that show the income and tax items (which you can edit), and then the net income is calculated and displayed.</p>
  
  <p>This works great, and is the standard approach I've seen used in tutorials. However, if I just add one more controller that depends on some of the same data and logic, it begins to unravel:</p>
  
  <p><strong>ExpensesCtrl</strong> controller for expenses which will in the end calculate the surplus (<em>net income - expenses</em>):</p>
  
  <pre><code>app.controller('ExpensesCtrl', function ($scope, BudgetData) {
      var categoryTotal = function (category) {
          var total = 0;
          angular.forEach(category.transactions, function (transaction) {
              total += transaction.amount;
          });
          return total;
      };
  
      $scope.model = BudgetData.get(function (model) {
          $scope.totalIncome = categoryTotal(model.income);
          $scope.totalTaxes = categoryTotal(model.taxes);
          $scope.totalExpenses = categoryTotal(model.expenses);
      });
  
      $scope.netIncome = function () {
          return $scope.totalIncome - $scope.totalTaxes;
      };
  
      $scope.surplus = function () {
          return $scope.netIncome() - $scope.totalExpenses;
      };
  });
  </code></pre>
  
  <p><strong>budget.json</strong> adds the expenses data:</p>
  
  <pre><code>"expenses": {
      "transactions": [
          {
              "description": "Mortgage",
              "amount": 12000
          },
          {
              "description": "Car Payments",
              "amount": 3600
          }
      ]
  }
  </code></pre>
  
  <p>Then on a separate part of the screen I have a section that uses this controller and uses a repeater to show the expense items, and then re-displays the net income, and finally shows the resulting surplus.</p>
  
  <p>This example works, but there are several problems (questions) with it:</p>
  
  <p><strong>1)</strong> In this example I've managed to keep most of my controller's logic out of the callback function, but all controllers start out in a callback because everything depends on the model being loaded. I understand this is the nature of javascript, but angular is supposed to reduce the need for all of these callbacks, and this just doesn't seem clean. The only reason I was able to take some of the logic out of the callbacks here is because of the magic that angular does under the hood to substitute a fake object for the model until the model gets loaded. Since this 'magic' is not intuitive, it's hard to tell if your code will work as expected.</p>
  
  <p>Is there a consistent way people deal with this? I really don't want some elaborate solution that makes this 101 intro app into something really complicated. Is there a simple and standard approach to restructuring this code somehow to avoid so many callbacks and make the code more intuitive?</p>
  
  <p><strong>2)</strong> I have a bunch of repeated logic. The <code>categoryTotal</code> and <code>netIncome</code> logic should only be in one place, and shared between controllers. These controllers are used in completely separate parts of the screen, so they can't use scope inheritance. Even when using scope inheritance there could be problems, because the child controller's scope can't depend on the parent scope's model being loaded even when its own model is loaded.</p>
  
  <p>The <code>categoryTotal</code> logic is just a helper function that isn't tied directly to the model, so I don't know where you put generic helper functions in angular. As for the <code>netIncome</code> which does directly depend on the model and needs to be in the scope, it would be possible to add it to the service or the model. However, the service should only be concerned with retrieving the model from the server, and the model should just contain data, and be as anemic as possible. Also, it seems like this kind of logic belongs in a controller. Is there a standard way to deal with this?</p>
  
  <p><strong>3)</strong> Every time the service is called to fetch the data, it does an http request to the server, even though the data is the same every time. The model should be cached after the first request, so there is only one request made.</p>
  
  <p>I realize I could handle this in the service. I could just store the model as a local variable and then check that variable to see if the data already exists before making the request. It just seems odd that none of the tutorials I read even mentioned this. Also, I'm looking for a standard 'angular' way of dealing with it.</p>
  
  <p>Sorry for the incredibly long post. I would really like to keep this app at the 101 intro level, and not get into really complicated areas if possible. I'm also hoping there is a standard 'angular' way to deal with these problems that I have just not come across yet.</p>
  
  <p>Thanks in advance!</p>