Angular Structure: Refactoring for Growth | John Papa

John Papa

Evangelist on the loose

Angular Structure: Refactoring for Growth

...

Your Angular app is growing and you want your structure to adapt with it. Let’s explore one way you can approach this.

As your app grows it becomes even more important to structure it in a way that makes it easy to manage and maintain it. I recently posted a common technique I use when I create a new app to help structure it. A simple structure by type is easy out of the gate, as the app generally starts with a single set of features. This usually starts as the first module you write. Now fast forward and imagine you are working on an app that has a handful of modules, with dozens of views and controllers. How do you organize your code now?

Options for Managing Growth

I like the type organization (folders for controllers and views, for example), but as an app grows, instead of putting that at the root and putting all views and controllers in their own folders, sometimes it makes more sense to organize them 1 level deeper into feature areas. For a similar approach, see Cliff Meyer’s great post. We tend to look for the one right answer, but often there are many good options. You have to choose what feels right for you.

So how might this look? There are a lot of ways we could do this, but let’s focus on two options side by side. NgStructureCompare

Sort By Type

On the left we have the app organized by type. Not too bad for smaller apps, but even here you can start to see it gets more difficult to find what you are looking for. When I want to find a specific view and its controller, they are in different folders. It can be good to start here if you are not sure how else to organize the code as it is quite easy to shift to the technique on the right: structure by feature.

Sort By Feature

On the left the project is organized by feature. All of the layout views and controllers go in the layout folder, the admin content goes in the admin folder, and the services that are used by all of the areas go in the services folder. The idea here is that when you are looking for the code that makes a feature work, it is located in one place. Services are a bit different as they “service” many features. I like this once my app starts to take shape as it becomes a lot easier to manage for me.

Structuring for Modules

This structure by feature can be extended fairly easily once you start to gather multiple modules. When i see common functionality that can be extracted and re-used, I like to break that out into its own module. In the structure by feature notice that I have a common folder. In there I have another module named common that contains logging, progress bars, and other common features. Sometimes I break this out such that the modules are the first folder under the app folder. But in this case I just had 2 modules: common and the main app.

As the app grows even further, you can have many modules. That’s when I like to have the modules in their own folders under app. Specifically when the main app has very separate feature areas like point of sale and inventory, for example. Those could be their own modules. Then I’d also have some other common modules. See where this is heading? Separate silos of features that are easily separated (think Separation of Concerns).

Your Choice

Ultimately how you organize your code is entirely up to you and your team. Don’t feel married to your choice, you can adapt when it makes sense. The key is in keeping good separation and making it easy to find your code.

If you are interested in SPA, HTML5, Angular, BreezeJS or JavaScript patterns then you will love my upcoming course at Pluralsight, due out in October 2013. Or if you prefer Knockout and Durandal check out my courses on Pluralsight today.

tags: angular javascript
  • Jay Turpin

    John – where do you put your Jasmine or QUnit tests?

    • John

      Jay – In a test folder at the root. Not intertwined in the code.

      • http://www.codebetter.com/johnvpetersen John Petersen

        John,

        Suggest you create a separate project for JavaScript tests – just as you would for any other unit/integration tests.

  • http://mike-ward.net Mike

    I’ve never liked the sort by type layout but whenever I propose a different layout, I get push back from others. Thanks for posting this. Now I have some “ammo” for the next time. :)

    • http://www.codebetter.com/johnvpetersen John Petersen

      Pushback from refactoring in general or just this situation? The correlation between well factored code and code that is maintainable is no accident.

      • http://mike-ward.net Mike

        I was referring to putting controllers in a controller folder, views in a view folder, etc. How often do you use a controller with different views? Seems more appropriate to group by function or feature or page or something else.

        • http://www.codebetter.com/johnvpetersen John Petersen

          **
          How often do you use a controller with different views?
          **

          Frequently. Depends on what is initiating the request. Different views for different form factors. Unless of course, you have a completely adaptive UI

          • John

            I infrequently use a controller for multiple Views. It does happen, but I do not use multiple views for different form factors as I opt for responsive/adaptive design instead.

          • http://mike-ward.net Mike

            Even in “multiple form factors” situation you’re referring to I would still want the various views grouped with the controller.

            But more to the point, I think grouping feature X’s controller and views together apart from feature Y’s controller and views makes more sense. I usually end up going the other way since that’s what others are comfortable with.

          • John

            Mike – You hit on the real key: doing what is comfortable for the team. Really, that’s what matters in this case.

          • http://www.codebetter.com/johnvpetersen John Petersen

            Agreed, Organizing features in specific folders is a good idea. As with anything, different teams will have different requirements.

            I look at it this way – we work on products, which are made up of features., This ties into Scrum nicely. Organizing folders by feature makes a lot of sense. Again, YMMV.

  • mojam

    John I am new in SPA development and in learning stage (Learning from your Jumpstart SPA). My office decided to build up a large financial application (More than 130 tables) in ASP.MVC and they are much interested about SPA. Now my question is which one would be better for this application? SPA with breeze or your Intermediate SPA? Thanks in advance.

    • John

      mojam – It depends on your experience and what you feel comfortable with. The SPA Jump-Start uses a framework (durandal) to get you there. The intermediate course doesn’t use a framework. using a framework is nice (and I recommend it), but it is also good to see how you can roll your own.

      • mojam

        John
        Thanks for your advise. I also like Durandal to develop but with Breeze need to load metadata of my project in client. Though my database is large. Wouldn’t it take cost during loading?

        • http://sampathloku.blogspot.com/ Sampath Lokuge

          Hi Mojam,

          You have to careful here,When you try to use SPA with Enterprise level Applications.I asked same question from John,But unfortunately he didn’t give me the answer.So then I asked it from SOF. Here is the answer for that.Check this before select the SPA for large Apps.

          http://stackoverflow.com/questions/19679369/single-page-application-for-enterprise-level-systems

          • John

            Sampath – It all depends on the app you build, the features, the reach, devices, your skills, and more. You can’t generalize. If you ask a specific question with those in mind, we can answer. But I cant tell you any specific tech is good for “enterprise” or “Pro” apps.

            I get a lot of question and I do not always get to them all. Sorry if I missed yours somewhere.

    • http://michaelcalkins.com/ Michael Calkins

      I jumped right into Angular and am using it to build a SPA for healthcare and education. Even though I’m pretty new to this. Just follow John’s example on the right, use angular ui router, and you’ll be fine. My biggest issue was organizing a large app like the left picture.

  • Daniel

    “On the left we have the app organized by type”
    “On the left the project is organized by feature.”

    Something’s wrong here…

  • Pingback: Angular Structure: Refactoring for Growth | Cod...

  • Pingback: AngularJS Highlights – Week Ending 29 September 2013 | SyntaxSpectrum

  • Pingback: Create an Angular App in Seconds with Hot Towel | John Papa

  • Vladimir

    John, How did you show the splash-page, the element has a stribute data-ng-show=”false” from the start.

    • John

      Vladimir – The data-ng-show doesn’t kick in til Angular is ready. So in this case, I take advantage of that short delay and show the splash page. Once Angular kicks in, it hides it.

    • Martin

      I don’t know about John Papas template (just found this page via Google), but I’d assume it’s this case:

      First the HTML is loaded, including this splash screen. HTML does not know what “ng-show=false” means, so it will display the splash screen. Next (and meanwhile) the scripts are loaded. Once all scripts are loaded AngularJS is executed and your Angular App is created. This will manipulate the DOM, looking for directives. It will find the “ng-show=false” directive and hide the splash screen.

      So basically: The splash screen is shown until your Angular App is started.

      • johnpapa7

        @disqus_i3vsBEcO9W:disqus @disqus_JFwwM2ZBSi:disqus – That’s exactly hat happens.

  • 2Buku4U

    Since most all MVC apps regardless of platform i have worked with over the years have conventions that require the structure on the left (By Type), I find it quite funny to hear developers say the structure on the right (By Feature) is recommended. I guess software developers get bored after awhile and then find ways to contradict themselves just to be able to promote something different. If organizing MVC parts “By Feature” is better then why has that not been the case for the last 10 years? Watching angularjs vids I hear the devs warning that with “By Type” after you get 10 or so files in there then it’s hard to find stuff… LMAO this is the stupidest reason I have ever heard of to influence file structure of a software project. The IDE’s I use have search functions to help find files… Next you will have someone influential telling us to put one file per folder just because no one else is doing it that way.

  • http://nerdcraft.se Kimpo

    @johnpapa7:disqus

    Lets say i’m trying to organize my angular project files by feature and have a clientcontactform.directive.js which is quite specific for clients and then a bunch of other more generic directives which are used in several places in the application.

    Where do i put the client specific directive? Within the client module folder or generic directives folder?

  • Md. Shohel Rana

    My need vsix setup file for hottowel.angular.breeze. can you give me that setup file so that i can develop my site.

  • http://Meh.com Brett Raven

    Hi John, great stuff here!

    I have a question regarding your controller layout. Specifically I was trying to get my head around your utilisation of your ‘vm’ var. (example in the dashboard code

    var vm = this;
    vm.news = {
    title: ‘Hot Towel Angular’,
    description: ‘Hot Towel Angular is a SPA template for Angular developers.’
    };
    vm.messageCount = 0;
    vm.people = [];
    vm.title = ‘Dashboard’;

    Why would you use vm reference instead of $scope? It appears to be well thought out but I am trying to understand the advantages.

    Cheers,
    Brett

    • johnvpetersen

      Candidly, I’m not sure why one would need/want a separate SPA template framework on top of Angular. You end up with one abstraction over another. IMO, if one is going to use something like Angular, you want to color as close as possible within the lines and remain as much as possible within that paradigm as possible. I see too many issues when new versions of Angular come out and incompatibilities with other tools. Angular has $Scope there for a reason and I would contend that is what people should use.

      As for organizing large apps, I create an areas folder and then under that, a folder for each area, feature or however you choose to organize your app. Under each folder, you’ll find the code files for the model, controller and view. Any common code, templates, etc – go into a common folder. Where you put that is entirely up to you.

%d bloggers like this: