How to Improve an AngularJS Application Code
Tags: angular
Published: 2019-01-26 08:47:49

---
title: How to Improve an AngularJS Application Code
published: true
description: A few coding practices to improve AngularJS App Code
cover_image: https://thepracticaldev.s3.amazonaws.com/i/ptr6rk88apjjx86w1810.png
tags: AngularJS, Angular
---

AngularJS is getting more and more stable with every new release eliminating the waste and focusing on the advancement. Also, the big Software companies are now starting to rely on it to handle large scale projects.

In this post, we tried to highlight many such features which can in some way improve an AngularJS application or lead the way for a better implementation. These are suggestions which revolve around the Angular, TypeScript, ReactiveX, and some coding best practices.

## TOC
  * [Use trackBy with ngFor](#tip-1)
  * [Fixed value or a variable, decide](#tip-2)
  * [Use of lightweight lettable operators](#tip-3)
  * [Use an operator when it matters the most](#tip-4)
  * [Load a module when needed](#tip-5)
  * [Declaration with type](#tip-6)
  * [Apply lint rules](#tip-7)
  * [Split components to keep them small](#tip-8)
  * [Make components specific for display purpose](#tip-9)
  * [Remember DRY](#tip-10)

### 1. Use trackBy with ngFor <a name="tip-1"></a>

In Angular, we mostly use the ngFor directive for iterating over a list of items. Here the problem is that you can't change the value of an object during the loop. It is simply because Angular doesn't track the items in the list and have no knowledge any addition or deletion.

However, if we add the trackBy option, then it can let Angular know which item has changed and will make changes specific to that only.

With the trackBy option, we can attach a function inside the ngFor clause which returns a unique identifier for each list item.

Angular Code using ngFor
```javascript
<tr *ngFor="let set of sets;">
    <td><h1>{{set}}</h1></td>
</tr>
```
Angular code using ngFor with the trackBy option
```javascript
// Update the template
<tr *ngFor="let set of sets; trackBy: trackSet">
    <td><h1>{{set.name}}</h1></td>
</tr>

// Update the component
trackSet(index, set) {
    console.log(set);
    return set ? set.id : undefined;
}
```
### 2. Fixed value or a variable, decide <a name="tip-2"></a>

You should maintain a clear distinction between what you use as a constant and those which will change their values.

Like many other languages, Angular also gives you built-in identifiers to disassociate a const from a variable.

Angular code without considering const vs. let guideline
```javascript
let pen = 'parker pen';
let myPen = `My ${pen}`;
let yourPen = `Your ${pen};
if (iHaveParker) {
    myPen = `${myPen} is the best`;
}
if (youHaveParker) {
    yourPen = `${youPen} is the best`;
}
```
Angular code using const vs. let guideline
```javascript
const pen = 'parker pen';
let myPen = `My ${pen}`;
let yourPen = `Your ${pen};
if (iHaveParker) {
    myPen = `${myPen} is the best`;
}
if (youHaveParker) {
    yourPen = `${youPen} is the best`;
}
```
### 3. Use of lightweight lettable operators <a name="tip-3"></a>

With ReactiveX (RxJS) 5.5, we saw the introduction of lettable (a.k.a. pipeable) operators.

More than operators, these are pure functions. They work as standalone operators replacing methods on an observable.

They’re pretty lightweight, turn your code highly re-usable and can reduce the overall build footprint.

Angular code without lettables
```javascript
import { from } from 'rxjs/observable/from';

const numlist$ = from([1, 2, 3, 4, 5, 6, 7, 8, 9]);

numlist$
  .filter(x => x % 2)
  .map(x => x * 2)
  .scan((acc, next) => acc + next, 0)
  .startWith(0)
  .subscribe(console.log)
```
Modified Angular code using lettables
```javascript
import { filter, map, c } from 'rxjs/operators';

const doEven = filter(x => x % 2);
const doSum = reduce((acc, next) => acc + next, 0);
const doDouble = x => map(value => value * x);
```
### 4. Use an operator when it matters the most <a name="tip-4"></a>

When you about to use an operator with the observables, select one after a careful assessment. Here are some quick examples of such situations.

a) If there comes a new emission and you wish to ignore the ones already occurred, then use the switchMap.

b) For concurrently handling all the emissions, use the mergeMap.

c) For handling the emissions one by one according to their entrance, use concatMap.

d) To suspend all new emissions while taking care of the current one, use exhaustMap.

It is a best practice to go with the single operator at a time instead of grouping multiple ones to gain the same effect.

### 5. Load a module when needed <a name="tip-5"></a>

It is called lazy loading, and it's not a new concept at all. However, apply it to the Angular code as well. For example, load an Angular component only when the application needs it.

With the lazy-loading enabled, the application will load a bit faster. Its boot time will improve by loading only the required set of modules.

Angular code w/o lazy loading
```javascript
// File: app.routing.ts
{ path: 'not-lazy-loaded', component: NotLazyLoadedComponent }
```
Angular code with lazy loading
```javascript
// File: app.routing.ts
{ 
  path: 'target',
  loadChildren: 'target.module#TargetModule' 
}
// target.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterModule } from '@angular/router';
import { TargetComponent }   from './target.component';
@NgModule({
  imports: [
    CommonModule,
    RouterModule.forChild([
         { 
             path: '',
             component: TargetComponent 
         }
    ])
  ],
  declarations: [
    TargetComponent
  ]
})
export class TargetModule {}
```
### 6. Declaration with type <a name="tip-6"></a>

Dynamic typing is a prominent feature, but it's best to specify the type while setting up variables in the code.

If we don't mention the type of variables, then it gets assigned at runtime based on the value. Sometimes, we could fall into problems due to this.
```javascript
const a = 1;
const b = 'x';
const c = a + b;
console.log(`Value of c is: ${c}`)

// Result
Value of c is 1x
```
In the above code, the problem is that we expect "b" as a number too. Such issues will not occur by giving them an appropriate type at the time of declaration.
```javascript
const a: number = 1;
const b: number = 'x';
const c: number = a + b;

// This will give a compile error saying:
// Type 'x' is not assignable to type 'number'.
```
### 7. Apply lint rules <a name="tip-7"></a>

We can improve the code by passing it through the lint rules. It will highlight coding issues instantly.

There is "tslint" which has built-in options such as "no-any," "no-magic-numbers", "no-console". We can set them inside the "tslint.json" to make them active for the code.

Angular code w/o lint
```javascript
public ngOnInit (): void {
    console.log('Simple message');
    console.warn('Warning message');
    console.error('Error message');
}
```
Upon execution, the code will run successfully and show the below in the console:
```javascript
Simple message
Warning message
Error message
```
Angular code with lint
```javascript
// File: tslint.json
{
    "rules": {
        .......
        "no-console": [
             true,
             "log",    // console.log disabled
             "warn"    // console.warn disabled
        ]
   }
}
// File: xcomponent.ts
public ngOnInit (): void {
    console.log('Simple message');
    console.warn('Warning message');
    console.error('Error message');
}
```
Upon execution, lint will show errors for "console.log()" and "console.warn()" statements. But there will not be any errors for the "console.error" as it was not in the configuration.
```javascript
Calls to 'console.log' are not allowed.
Calls to 'console.warn' are not allowed.
```
### 8. Split components to keep them small <a name="tip-8"></a>

If there are code-heavy components in your code, then pick and carve them into smaller pieces. See to make them as independent as possible so that they could work in most of the scenarios.

You can split a component if it doesn't have any particular logic and accepts inputs and processes them accordingly.

Such components are also known as Dumb because they are simple and have less prone to errors.

### 9. Make components specific for display purpose <a name="tip-9"></a>

Prevent components from adding any business logic other than the display related. It is best to limit them to show the data processed by the application.

Their purpose is to present the data and control how the view should operate. Don't mess them with any business logic instead have appropriate methods or services for them.

### 10. Remember DRY <a name="tip-10"></a>

You should not have the same code copied at several places in your application. Encourage regular code reviews in your team to spot any such malpractices sooner.

Maintaining duplicate code is an awful task and can quickly turn into a nightmare. Hence, you have to identify these problems as early as possible and stop a simple infection to become the ultimate decease.

Imagine if you are at the end of a release and have a problem to fix in such a code, then all affected area will need changes. It would only quadruply the dev and testing efforts.

### Footnote

A developer's role is not only to produce robust and quality applications but also to make sure that they could sustain a desirable level of load as well.

And there is no magic wand which can instantly improve the quality. It is only possible by enacting the coding basics from the inception of the project and finding as well as doing changes to address challenges as and when they occur.

You can refer and learn more angular tips and best practices from this post on [angularjs tips and trics](https://www.techbeamers.com/angularjs-tutorial-beginners-essential-tips-tricks/ "AngularJS For Beginners – Essential Tips And Tricks").