Failure is the key to success; each mistake teaches us something article This originally appeared on dormoshe.io Angular is a new platform. We learn how to use it, how to optimize the application and how to improve our code. As part of being team members, we do code reviews and trying to improve each other skills. As part of the code reviews and reading of code examples on the web, I pay attention to some common mistakes of Angular developers. . It can be a junior or an expert developer, we all make mistakes in the code In this article, we will cover the top common mistakes, and we will understand how to fix them. Each of those can be an idea to a full article. We will cover them briefly but in an exhaustive manner. Let’s start with Terminology — Angular vs Angular 2 vs Angular 4 vs Angular x+ 😅 The new Angular is not just a new version of Angular. It’s a rewrite of the framework. So now we have the old Angular 1 and Angular 2 and Angular 4 and in the near future Angular 5. But the changes between Angular 2 and Angular 4 aren’t as the changes between Angular 1 and Angular 2. Angular 4 is not a rewrite. It’s a new version of Angular 2 with bug fixes and new features. Actually, in the semantic versioning approach, every six months we will get a new version of Angular. So, with all the new versions, there is a confusion with the terminology. It’s not convenient to search for learning materials in Google, questions in Stack Overflow or just talk with your partners. In order to solve this frustrating issue, the Angular team decided about the names terminology. , just Angular. The old Angular, Angular 1, is called AngularJS and the new Angular 2/2+/4/5 is called Angular Another terminology change is the 3rd party libraries names. Sometimes, a library is called by the prefix. When Angular version 2 was released, libraries started to use the prefix . When Angular version 4 was released, a new terminology trend appeared. The terminology is to use the prefix, because Angular use the semantic versioning and every six months a new version will be released. So, for example, the name of , changed to and there is no reason to change it in the future. ng- ng2- ngx- ng2-bootstrap ngx-bootstrap ngOnChanges vs ngDoCheck AngularJS has the feature to notify on value change. Angular dropped the watch and scope, and now we have the component inputs as properties. Besides, Angular gives us the lifecycle hook. In order to improve the run time of the updates, The value of the input, in this case, is the to the object. watch ngOnChanges the **OnChanges** event doesn’t emit when a deep field of the input property changed. reference The log entries appear as the string value of the property changes. But the does not catch changes to power ngOnChanges hero.name Many developers don’t know this and fall into this trap. To solve this problem, there are various solutions: Use ngDoCheck Use immutable value as the input Split the input value to multiple inputs Use subscriptions The lifecycle hook is the common way to solving this issue. This hook is called when the change detection process runs. You need to be careful on using this hook because the changed detection usually runs a lot of time per minute. ngDoCheck Zombie Subscriptions — The Lack of unsubscription When you subscribe to an observable or event in JavaScript, you need to unsubscribe to release memory in the system when you finish to use it. Otherwise, . you will have a memory leak Example for unsubscribing in a component’s ngOnDestroy hook Mostly, when you subscribe in a component, the better place to unsubscribe is in the lifecycle hook. When you subscribe in a service, there is no lifecycle hook, so you need to initiate it by yourself. OnDestroy The lack of unsubscriptions is because the developers don’t know that they need to do so or because they forget to unsubscribing. In order to help us to solve this problem, were developed. libraries and methods Over/extra unsubscription Besides the mistakes of zombie subscriptions, there are cases that the unsubscribe operation is automatically done by Angular. An example of such cases is when you use the async pipe. Over unsubscription operation example Another examples can be finit subscriptions like and . Observable.timer(1000).subscribe(…) http.get(‘http://medium.com’).subscribe(…) There are Rxjs’ methods that unsubscribe by their-self. For example, take(n), takeWhile(predicate), first() and first(predicate) are some of them. So, and knowing those methods is viable to make this mission correctly. you need to be careful with the mission of unsubscription @Component.providers vs @NgModule.providers As part of the new mechanism of Angular, the Hierarchical Dependency Injection, we can instantiate a service more than one time, unlike in AngularJS. In the old AngularJS, the services are singletons. Suppose we have a heroes service to fetch our lovely heroes: Hero service As we can see, the service fetches the data in the constructor. Also, there is a method to get the heroes. Everything is fine. getHeroes Now the hero component: Wrong use of provider The declare the provider in the array and inject it in the constructor. The problem withthis code is that . So, the service will fetch the data by HTTP request multiple times because of the Hierarchical DI. HeroComponent HeroesService @Component.providers every **HeroComponent** instance will instantiate a new instance of the **HeroesService** The solution to this problem is to declare the service in the : @NgModule.providers Correct use of provider Now, the provider will be instantiated only one time for all the instances. This will happen because, . There is no need to export a provider in the array. It will be done automatically. HeroComponent when a provider is declared in the **NgModule** , it will be a singleton and all the other modules will be able to use it @NgModule.exports Mutating the dom directly Angular is no more a framework for the web. One of its strengths is that it allows us to decouple the application code from the renderer, which in turn makes it possible to write applications that can be executed in the browser, on the server, or even as native apps. Angular is a platform. The decoupling also gives us more abilities like using AOT (ahead of time compilation) or web workers. Ahead of time compilation means to compile the application templates in the build time of our server. AOT can be used instead of the standard JIT compilation that runs in the browser. When we use AoT there is no need to include the big package in our bundle, so the bundle size and the load time are lower. So it is crucial. @angular/compiler One of them is not to mutate the DOM directly using jQuery, document object or . If we want to use this ability now or in the future, we need to keep some constraints. ElementRef.nativeElement Mutate the dom directly — the bad way As you can see, the method has three lines of code, which demonstrate three ways to mutate the DOM directly. The first line is by jQuery. The second is by the , and the third is by the global object. doBadThings ElementRef.nativeElement document The Angular way to mutate the DOM is via the service (in v4, Renderer in v2). [Renderer2](https://angular.io/api/core/Renderer2) Mutate the dom via Renderer — the recommended way In this way, we call the of the renderer with three arguments. This function goal is to change/add a property to an element. The three arguments are the instance, the property name, and the property value. The is a wrapper to the view mutation layer. When we are in the browser, the default renderer will be used. When the application runs on another platform, like a phone, . This renderer needs to implement the renderer class interface and to beinjected as the default Renderer class by the DI mechanism. setElementProperty elementRef Renderer the renderer will be replaced with another suitable renderer “Don’t ever never” touch the DOM directly Declaring a component multiple time A Component is the common building block in an Angular application. Every component needs to be declared in a in order to be available for the views. To specify that a component is a member of a , you should list it in the array. NgModule NgModule @NgModule.declarations . If a component is declared in multiple -s, the Angular compiler will . For example: There is no possibility to declare a component in more than one **NgModule** NgModule throw an error As you can see, the component is declared in the and also in the . The need for the same component in . When that happens, we should think . If one module is a child of the other module, the solution will be: HeroesModule AnotherModule more than one module is ok what is the relationship between the modules Declare the HeroComponent in the child module by the child’s NgModule.declaration Export the HeroComponent by the child’s array NgModule.exports Import the child module by the parent’s array NgModule.imports Parent-child modules relation If this is not the case, we need to declare another that will be a . The solution will be: NgModule module of shared stuff Declare and export the HeroComponent in the shared module Import the shared module in both of the modules Shared module solution Conclusion Making a mistake it’s ok. All of us do that. Even when we write a bunch of code and read it later, sometimes we don’t understand why the code was written like that. Turning a blind eye is the fatal error — learn from your mistakes As developers, we always need to improve our skills. Making a mistake is one of the best ways to become a stronger and a better developer. We need to write the mistakes as a side note, maybe in a checklist, and we should ensure that , the code will be written properly. The big mistake is to see the mistake and turning a blind eye. in the next time You can follow me on dormoshe.io or Twitter to read more about Angular, JavaScript and web development.
Share Your Thoughts