There are lots of tutorials on the internet showing how to start your adventure with the newest Google framework. But what is really missing are some guidelines presenting a bigger picture of the ecosystem with its pros and cons. I started working on a commercial product in Angular while it was still in its early release. Therefore, based on my experience, I will try to provide some guide for beginners or those of you considering using Angular in your applications.
Angular naming issue
First let’s crack down the naming issue. You probably heard of Angular 2, then out of nowhere Angular 4 appeared. All you really need to know is that Angular uses semantic versioning so any breaking change will result in the higher number at the beginning. We can expect Angular 5, 6,7 … and so on in the near future. If you are interested what has happened with Angular 3 and other mysteries of the versioning, there is a great blog post about it here. From now on we will call the newest framework just Angular, and add only the specific version number where it is really crucial. Although it should be clear now, it isn’t so easy where it comes to looking for educational materials on the internet. The Angular team has released a lot of public alpha/beta/rc releases before the official 2.0 version. Also people at that time were referring to the newest angular as Angular 2. Unfortunately this brings a lots of confusion when you search the web. There are stackoverflow questions/answers which refer to alpha/beta release but the title stands for Angular 2 (without explicit version). You just need to be careful and always check the publication date if there is no explicit info about the framework version. Hopefully, the situation will be more stable as more and more latest angular materials are showing up with proper version naming.
Remember that the language is always a foundation on which frameworks are build. Frameworks show up and disappear, but the language stays so it’s really crucial to understand it.
Another thing you should be familiar with before you start is reactive programming. Angular heavily uses RxJS library and this video provides a really great overview and basics which will be necessary to work with Angular on a daily basis. Be careful when you look for materials on RxJS topics because there are some differences between RxJS 4 and 5 (Angular uses the newest one). So if you find code and copy paste won’t work, be sure to verify its content within this document.
Ok let’s assume that you have learned RxJS, Typescript and completed “Tour of Heroes” tutorial. Maybe even you completed some others tutorials as well. Is it enough to feel confident and start with serious application? At this point you should ask yourself a few questions.
Questions you know answers to before the development
Do I know how to structure my project?
Do I know how to handle models definitions?
Do I know how to manage state in my application?
Do I know how to manage all kinds of translations?
Do I know how to combine third party packages?
Do I know how to customize a build process?
Do I know what is the Ahead of Time compilation and what pros and cons come with it?
Do I know how to use lazy loading?
Do I know any issues/bugs and solutions to them?
Do I know how Dependency Injection works especially in combination with lazy loading?
Do I know what shadow dom is and how angular emulates it?
Do I know how to override third party components styles?
Do I know how to write unit tests?
In fact the list goes on, but if you can’t answer ‘yes’ on more than 5 of them, you probably should continue reading. To be honest, I don’t think that you need to be an expert in Angular before going to production but it is good to have a bigger picture beforehand. Sooner or later some problems connected with those questions will occur. In the case of enterprise level application it is better to know your enemy before the actual battle begins.
How to structure my project?
The Angular team have done the homework and this time there is an official guideline showing how the project structure and code organisation should look like. You can find it here. Also, the Angular-cli will help you to keep the structure intact. You should be familiar with this tool and you can find more info about it here.
How to handle models definitions?
How to manage state in my application?
One of the good practices is to have “Smart” and “View” components. Smart components aggregate the view ones and manage state. View components only receive inputs to display data. It is a nice approach. However, there are situations where having nested smart components is much more cleaner. Remember that if nested components can’t perform any actions you need to pass events to parent components and handle action there or even pass it further. It’s not always worth additional code and complexity so you need to find balance between thoughtless applying a design pattern and using it for some reason.
Another approach which is well known from React.JS applications is Redux. It’s a design pattern which can be used with any framework. Probably its best implementation for Angular is ngrx. You don’t have to look for ngrx materials only. You can learn Redux pattern from React.js tutorials as well. It’s all about the concept. But if you decide to use Redux it’s a good practice to use it across the whole application and not mix with other approaches, so think it through before applying to your application.
How to manage all kind of translations
Due to the architecture decisions Angular team has made according to AOT (Ahead of Time) compilation you will need the whole application build per language. It means that if you want to support three languages, switching between them doesn’t mean reloading some kind of json and interpolating fields in real time (like it was in AngularJS). It means reloading the whole application (for example reading from different directory with language prefix but it’s backend specific how it will be handled). This is great solution in terms of performance but is not very elastic. When your clients need dynamic translations (for example editing them from admin panel and real time preview on target application) you can’t use a built-in solution without some tweaks on both sides (backend and frontend). One option is to use existing solutions simulating behaviour known from AngularJS. One of them is the ngx-translate package. Another option is to build own directive which will replace HTML elements with i18n attribute in runtime based on json returned from backend. First option implicates that you can’t use integrated i18n tool provided by the Angular team, so you are totally dependent on that external library. Second lets you use existing tools with some adjustments on both sides. Your decision should be made on client requirements, so make sure if dynamic translation are relevant. If you decide to use a built-in solution, this article will be really helpful.
How to combine third party packages?
In comparison to AngularJS amount of external npm packages is really low (at the time of writing). So there is high probability that you will need to make some wrapper around available jquery library or write something on your own. Fortunately things like Bootstrap or Material Design is being rewritten for Angular pretty fast. Most popular Bootstrap implementation is and official Material Design (still in early beta at the time of writing)
Integration in Angular with external packages is pretty straightforward. Thanks to the Zone.js architecture in most cases we don’t need to worry about detection changes issues known from AngularJS. Also, connecting to Dependency Injection or module system looks much cleaner and easier than AngularJS equivalent.
What is the Ahead of Time compilation (AOT) and what pros and cons come with it?
There is a good section in Angular docs about it, so definitely take a look at it. However, you need to be aware that this quote:
Do I know how to customize a build process?
At this moment you are probably happy using the Angular-cli with few simple commands to build and run development server for your application. However, at some point there might be a requirement to change a build process. For example, you might want to integrate a WASM module or you need to maintain some library written in coffeescript and want to inject it on the fly to the main bundle.js file. You probably still want to use one integrated build process. Hopefully, the latest version of the Angular-cli has the ‘ng eject’ command. It lets you output webpack.config file which seats under the hood of the Angular-cli. The disadvantage of this solution is that you have to maintain this file by yourself so you must get acquainted with the whole webpack ecosystem which previously was hidden under a nice abstraction layer (Angular-cli) which now you can’t use anymore. Webpack for sure isn’t easy to master, maybe you won’t need to use it directly at all, but I recommend that you learn its basics just to get head around what’s going on when you hit build command in the Angular-cli.
What is Shadow DOM and how does Angular emulate it?
Frontend developers should be familiar with the Shadow DOM concept. This is a good place to start to learn what is it all about. Although this feature is still not adopted by all browser vendors, Angular is emulating Shadow DOM by using special attributes generated at compilation phase. You can learn more about it from the Angular perspective here.
Any known issues/bugs and solutions for them?
Angular is still in a very active development (both in terms of bug fixes and new features). Therefore, if you encounter any problem which seems to be related to Angular and not your code you should at first update your dependencies version to check if the issue was resolved in latest updates (there is high probability that it was). Even though we are now at the stable release you can encounter some strange edge cases which can be related to existing bugs. If updating doesn’t help visit both Angular-cli & Angular repository and look for your particular issue, probably there is some ticket for that. To bear out my thesis I can present you a simple example. Look at this issue. For the most of the time I didn’t even knew that it existed. Until one day I needed to adjust one of my modules for lazy loading. Unfortunately, this module was using named router outlets. When you are using lazy loading you define root path for the module probably inside app.routing.module file and leave empty root path in lazy loaded module. This works like a harm without named router outlets but not with them. There was no error message, routing just stopped working which was a very unpleasant experience. I suspected that it was connected with lazy loading, because before introducing it, everything was fine right?. As you already know after reading this post, that’s not lazy loading mechanism problem. But it took me few hours to get to this point. There are more bugs and situations similar to this. I managed to bypass this problem by giving additional root name inside lazy loaded module but this results in longer browser addresses paths. Instead of ‘edit/user/ I had to use something like ‘edit/details/user’. Where ‘edit/details’ is places in app.routing.module and ‘user’ part in lazy loaded one. In my case I was able to do such thing, but in yours it might be impossible for some reason so let’s hope it will be fixed soon.
How Dependency Injection works especially in combination with lazy loading?
Although a DI mechanism is described in documentation there is a great article explaining it in details here. However,there is a really important note about DI which isn’t included in the article and DI documentation. It’s included in shared ngModules documentation here. It’s really easy to forget or just skip this note, and problems that can occur because of it can be really hard to debug. It’s so important that I will say it once again:
“Do not specify app-wide singleton providers in a shared module. A lazy-loaded module that imports that shared module makes its own copy of the service.”
I made that mistake with authorization service and you can just guess what happened. Don’t make the same mistake – read documentation carefully, several times.
How to write unit tests?
Unit test are one of the core features when it comes to Angular. Official docs have a whole section dedicated to that topic. What is really great about Angular is that you can test how component will be rendered without using selenium and fallbacking to e2e tests. Which results in better performance and can be easily combined with continuous integration systems. Testing isn’t an easy job (which may seems like it at the beginning) In fact learning how to write good tests takes probably the whole programmer’s career to master. In my opinion the best way to learn testing is in practice. Remember that having even a few most basic tests is better than none. So write tests whenever you can. There is a nice quote about testing in general “If you don’t test it now, you’ll just debug it later”.
I hope that your knowledge of Angular as a framework and ecosystem has broaden to the level that you already know if it is good fit for your project or what topic you need explore before diving in. It’s hard to explicitly say if Angular will be such success as AngularJS back in a day but I’m optimistic and see bright future in front of it. I believe that at some point it will be stable as a rock and number of reliable packages will outgrow AngularJS base.
If you are looking for more educational resources I encourage you to visit this website with valuable knowledge aggregated in one place.