title: AngularJS : How should controllers and factories/services be structured with a rich, hierarchical object model?
body: <p>I read these two great articles:</p>
  
  <p><a href="http://jonathancreamer.com/the-state-of-angularjs-controllers/" rel="nofollow noreferrer">The state of angularjs controllers</a> by Jonathan Creamer</p>
  
  <p>and</p>
  
  <p><a href="http://toddmotto.com/rethinking-angular-js-controllers/" rel="nofollow noreferrer">Rethinking AngularJS Controllers</a> by Todd Motto</p>
  
  <p>In these articles, the authors talk about the right way to use controllers (making them anemic bridges between the view and the model) and factories/services (where the business logic should really live).</p>
  
  <p>This is great information, and I was really excited to start refactoring the controllers on one of my projects, but I quickly found that the structure shown in the articles breaks down if you have a rich object model.</p>
  
  <p>Here's a recap of the setup from "Rethinking Angularjs Controllers":</p>
  
  <p>Here's the controller:</p>
  
  <pre><code>app.controller('InboxCtrl', function InboxCtrl (InboxFactory) {
  
      var vm = this;
  
      vm.messages = InboxFactory.messages;
  
      vm.openMessage = function (message) {
        InboxFactory.openMessage(message);
      };
  
      vm.deleteMessage = function (message) {
        InboxFactory.deleteMessage(message);
      };
  
      InboxFactory
        .getMessages()
        .then(function () {
        vm.messages = InboxFactory.messages;
      });
  
  });
  </code></pre>
  
  <p>and here's the factory:</p>
  
  <pre><code>app.factory('InboxFactory', function InboxFactory ($location, NotificationFactory) {
  
    factory.messages = [];
  
    factory.openMessage = function (message) {
      $location.search('id', message.id).path('/message');
    };
  
    factory.deleteMessage = function (message) {
      $http.post('/message/delete', message)
      .success(function (data) {
        factory.messages.splice(index, 1);
        NotificationFactory.showSuccess();
      })
      .error(function () {
        NotificationFactory.showError();
      });
    };
  
    factory.getMessages = function () {
      return $http.get('/messages')
      .success(function (data) {
        factory.messages = data;
      })
      .error(function () {
        NotificationFactory.showError();
      });
    };
  
    return factory;
  
  });
  </code></pre>
  
  <p>This is great and because <code>providers</code> (the factory) are singletons, the data is maintained across views and can be accessed without having to reload it from the API.</p>
  
  <p>This works just fine <strong>if <code>messages</code> are a top level object</strong>. But what happens if they aren't? What if this is an app for browsing the inboxes of other users? Maybe you're an administrator and you want to be able to manage and browse the inboxes of any user. Maybe you need multiple users' inboxes loaded at same time. How does this work? The problem is inbox messages are stored in the service, i.e. <code>InboxFactory.messages</code>.</p>
  
  <p>What if the hierarchy is like this:</p>
  
  <pre><code>                           Organization
                                  |
                __________________|____________________
               |                  |                    |
           Accounting       Human Resources            IT
               |                  |                    |
       ________|_______      _____|______        ______|________
      |        |       |    |     |      |      |      |        |
     John     Mike    Sue  Tom   Joe    Brad   May    Judy     Jill
      |        |       |    |     |       |     |      |        |
     Inbox    Inbox  Inbox Inbox Inbox  Inbox Inbox  Inbox    Inbox
  </code></pre>
  
  <p>Now <code>messages</code> are several levels deep in the hierarchy, and have no meaning on their own. You can't store messages in the factory, <code>InboxFactory.messages</code> because you have to retrieve messages for several users at a time.</p>
  
  <p>Now you will have an OrganizationFactory, a DepartmentFactory, a UserFactory, and an InboxFactory. Retrieving "messages" must be in the context of a <code>user</code>, who is in the context of a <code>department</code>, which is in the context of an <code>organization</code>. How and where should the data be stored? How should it be retreived?</p>
  
  <p>So how should this be resolved? How should controllers, factories/services, and rich object models be structured?</p>
  
  <p>At this point in my thinking, I'm leaning towards just keeping it lean and not having a rich object model. Just store the objects on the $scope injected into the controller, and if you navigate to a new view, reload from the API. If you <strong>need</strong> some data persisted across views, you can build that bridge with a service or factory, but it shouldn't be the way you do <strong>most</strong> things.</p>
  
  <p>How have other's solved this? Are there any patterns out there for this?</p>