Important best practices of Angular 1.x (my vision)

A lot of times when I review Angular 1.x code, that my team writes, I keep seeing same mistakes. Those types of mistakes I made myself when I first faced it. It took time for me to realize some important concepts, which are not very clear from the first sight. Another thing is that in Javascript and especially in Angular it's possible to do some single thing in several different ways. Each one of them is good for some particular case, but there would often be one that covers most of your needs. So to eliminate the need of explaining this several times, I want to write an article to refer to. As well it would be great to share article with community as well so that they can point me to my mistakes.

Build

Why did I put it first? Well, Angular has fairly easy setup, but as project grows proper build matters. And the most mature Angular 1.x build out there from my point of view is this Yeoman generator. So below I would just describe its main features.

Angular itself has module system. But it's a fact that it has nothing to do with loading Javascript into VM. Angular modules only specify how your application should be bootstrapped in a declarative way. That means that you need to insert all those <script> tags into HTML on your own. Initially, it doesn't look that bad, but in the end it gets annoying. You face another problem, when you go in production and realize that you need to concatenate and minify all your scripts.
So you want so that all your application script files in development mode were injected as is via <script> tag, but in production mode you need to have that single script file, which contains all the code. The first problem that comes out here is that you need to have different index.html files for development and production mode. And you know the problem, when something should be modified, it should be modified in several places and so on.
So what does this build does? It basically goes through your file system and finds all your javascript files in the app directory and injects them to the copy of index.html file created in temporary directory as <script> tags. If you are building your app in production mode, it will just add single <script> tag with minified code. It does the same with your bower dependencies. And how does it do it? Well if you look into index.html file you will notice following HTML comments.

<!-- build:js({.tmp/serve,.tmp/partials,src}) scripts/app.js -->  
<!-- inject:js -->  
<!-- js files will be automatically insert here -->  
<!-- endinject -->  

When build sees these types of comments it injects all your javascript files he's able to find in your file system as script tags. Magic!

Wise guys can say that there is another solution: you could use sourcemaps technique (this could be easily googled, don’t want to dig into explanations), but as from my experience it doesn’t work well. Sometimes when you jump to the line of code from chome dev console, it takes you to completely different file and line. As well it has some problems with watching local variables. Another thing is that doing concatenation every time takes fair amount of time, especially when you project is getting big.

There is several other cool things, that this build does, like ngInject usage, injection of bower dependencies, browsersync and many more. From my point of view, it would worth to review this build and just be aware of them.

Project structure

Project structure When you will look through the articles on internet which tell you about angular project structure, they suggest two types:

NEVER GO THE FIRST WAY. It’s bad, it’s hard to support, it’s a mistake, especially for big application. As I first discovered that boilerplate I talked in previous paragraph, it was pretty weird for me, that they even put templates and css near js files. I came from java world, where everything was kept separately. Now it’s all good, because I realized how convenient it is. Today I’m completely okay to put even unit tests inside appropriate modules. This way, you can easily do refactoring, delete modules, which are not used, switch them temporary off etc. When you modify some directive, you don’t need to think where its template is located, how is it named, because it’s always near. Same for styles and unit tests. It’s really cool.

Performance

Agular is not slow As I was learning Angular 1.x, a lot of times I either heard from colleagues or read on internet that Angular applications are slow. Right now I can't agree that. Angular is not slow.
When you're beginning to note, that your angular app is getting slow, first thing you need to think of is that you probably did something wrong. Well, Angular is very demanding in terms of performance. If you don't understand what's happening and write code just to make it work as expected, it will be slow for you. The reason why it can be so is because of Angular 1.x runs dirty checks in its $digest cycle practically every time you change something. And basically all performance optimizations are based on this technique. I will not point to all of them, because there's a nice article about performance optimizations: http://www.alexkras.com/11-tips-to-improve-angularjs-performance/ .
Okay, you did all of these optimizations and your app is still slow. You should probably take a look at libraries you're using. Probably some library just creates too many "$watch"ers. If so, then think if you need everything this library provides. Probably you can just implement features you need in pure Javascript.
Okay, you checked any other library and it's still slow. Then maybe Angular is not the case? Maybe your application is just too large or you have some ineffective algorythm out there?

Usage of controller in templates

Well, it took me a while to understand, why do you need to use controller in templates rather than plain scope properties. Initially I didn't pay a lot of attention to this problem, but it became really important at some point, when application became large. In few words, you should always have dot inside of bindings of your templates. As usual there are a lot of articles out there describing this particular problem. I will just point to one of them: http://blog.thoughtram.io/angularjs/2015/01/02/exploring-angular-1.3-bindToController.html

Sharing data between controllers

Share dat data And the last thing that seems pretty important for me is the question of sharing data between your controllers. At some point you will understand the need of it.
For example think about the simple application, which consists of two columns:
* A table of customers with filters * A map, which shows where your customers live. You want to make so, that when you change filters, the data should be changed in the table and inside the map. As well when you click some particular state on the map, filters should be changed as well and you should see in table items related only to some particular state.
It's obvious, that both table and map should have their own controllers. But here's the problem: they definitely share some data like filter values, filtered customer list etc. Where to put it? The most obvious answer is to put it to parent scope. But is this okay? I mean should parent know about the data, that it's children consume? Well, I think in this case no. If they will your controller in the end will become 10k+ line of code GOD controller. What about divide and conquer principle?
To eliminate this problem I suggest to put data of this kind to factories. This way you can simply inject that data into your controller. That easy! You will say: "No way! Those are singletones". Don't worry, so far I have never faced such problem when you need to create several instances of such model. Though it may happen, I don't think that this would be a big problem, that would be hard to resolve.
In any case as usual here are some nice article about this problem: https://thinkster.io/a-better-way-to-learn-angularjs/services
As well you can read following article and pay attention to first comment, if you have need of creation multiple instances of some factory which I described above: http://www.infragistics.com/community/blogs/dhananjay_kumar/archive/2015/05/04/how-to-share-data-between-controllers-in-the-angularjs.aspx

Conclusion

At the time of writing I don't see any alternative of Angular, when you need to build web app fast. With all respect to React, it's not that mature for now. Angular comes with a lot of useful features out of the box which allows you to create your app really fast.
In this article I described the most important things junior/mid Angular 1.x developer should be aware of. If you thing I missed something, please put that in the comment section. I would be glad to discuss that.