Related Blogs
Angular, developed by Google as a rewrite of AngularJS, is the most powerful framework for building dynamic programming structures. The main building blocks of Angular are modules, components, metadata, templates, data binding, services, directives, and dependency injection. It has a wide spectrum of other internal platforms for designing single-page applications using HTML, CSS, and Typescript. Typescript which is a superscript of the JavaScript framework is used for developing Angular applications. By using Angular technology, we can create more compatible and robust UI applications. Because of these functionalities, Angular is still one of the most popular frontend frameworks in 2022.
This insightful blog aims to bring into focus all the vital best practices Angular has that would ensure optimal implementation using Angular project for better performance and robust security.
Best Practices of Angular Development
1. Use Angular CLI
Angular CLI also abbreviated as Angular Command Line Interface is an end-to-end tool that helps in initialization, development, maintenance, testing and even debugging of Angular applications. CLI simplifies your overall process and can fastrack the schedules as well. So, when you are using CLI for your in house Angular applications, you must know the basic functions of Angular CLI.
Almost all versions of angular will support this method with some of the minor changes but with these ones as the main steps.
So, if you want to install CLI using NPM packages then you must use npm install -g @angular/cli
- Now if you want to create a new application then you can use ng new and can start a fully functional application right out of the box.
- If you want to use test shells for the development of components, routes, services, and pipes with a single command then you can use “ng create”
- For an app that is developed locally and needs to be tested in the developing phase, you can use ”ng serve” to test and find errors.
- For running local unit tests or end-to-end testing the most common command used is “ng test” command.
- To create a code shine, you can use ng lint.
- And then when you want to set up an Angular service worker, type ng add @angular/pwa.
You can use this to initiate the app development process using CLI. This is one of the easiest ways for developers to understand the code, even if some other developer has worked on it. This cuts a lot of cost and boosts the time of developers.
2. Use Features of ES6
ES6 stands for ECMAScript 6 which provides new syntax and features to make code that is more modern and more clear. It is continuously modernized with new functionalities and features. ES6 features like Let and Const, Arrow Functions, Object Literals string interpolation makes JavaScript programming easier.
3. Use trackBy along with ngFor
Using only *ngFor directive without trackBy function in an angular application will remove all the DOM elements and then it will recreate the DOM elements again in the DOM tree. So even when the same data is getting used, it’ll slow the application performance when there is a lot of data. That is why it is good to use trackBy along with *ngFor directive.
In component.ts file:
trackByBookCode(index: number, book: any): string { return book.code; } |
trackByBookCode(index: number, book: any): string { return book.code; }
In component.html file:
*ngFor='let book of books; trackBy:trackByBookCode'> |
*ngFor='let book of books; trackBy:trackByBookCode'>
4. Use Lazy Loading
Lazy loading is nothing but a process of loading different modules like documents, JS, CSS, videos, images, etc. It increases the speed of the application’s load time by breaking it into multiple packets and loading them on request, Rather than using other functions to load lazy load the modules, lazy loading can be useful while loading the large application.
Lazy loading will only load something when it is used. We can easily use the lazy-loading function to loadChildren instead of loading the component in AppRoutingModule routes configuration. A distinct app feature can be lazy loaded or loaded on demand rather than when application starts this is one of the best angular practices to follow..
const routes: Routes = [ { path: 'profile', loadChildren: () => import('./modules/profile/profile.module').then(m => m.ProfileModule) } ]; |
const routes: Routes = [ { path: 'profile', loadChildren: () => import('./modules/profile/profile.module').then(m => m.ProfileModule) } ];
5. Use Index.ts
Working with the index.ts file is not necessary at all but we use it because it helps to keep all correlated files in a single location. Now instead of remembering multiple source file names, there are some tiny import statements that will fulfill the purpose.
For instance, we have to test the /test/index.ts component and it will look like the screenshot below.
export * from './test.model'; export * from './test.service'; export { TestComponent } from './test.component'; |
export * from './test.model'; export * from './test.service'; export { TestComponent } from './test.component';
Now we can import all the files using
import { Test, TestService } from '../test'; |
import { Test, TestService } from '../test';
6. Avoid ‘any’ type
Avoiding the use of ‘any’ type can potentially lower the number of unexpected issues. Also, not using any type in our application will make the refactoring uncomplicated. The problems can be restricted by typing the specific variables and keeping others away.
7. Prevent Memory Leaks in Angular Observable
When we navigate from one component to the other component, the first component is destroyed and the other component initializes. The first component was subscribed to the Observable and now the component is destroyed. This can cause memory leaks.
We can prevent by following tips,
1. Using takeUntil()
TakeUntil keeps a check on second Observables and once the value of observables is generated then it will dispose of the subscription and the cycle gets finished.
this.authService.GetBookList() .pipe(takeUntil(this.ngUnsubscribe)) .subscribe(res => {this.bookList = res;}); ... ... ngOnDestroy() { this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); } |
this.authService.GetBookList() .pipe(takeUntil(this.ngUnsubscribe)) .subscribe(res => {this.bookList = res;}); ... ... ngOnDestroy() { this.ngUnsubscribe.next(); this.ngUnsubscribe.complete(); }
2. Using the Async pipe
It subscribes to an Observable or Promise and returns to the recent emitted value.
*ngFor="let item of bookService.GetBookList() | async"; {{item.bookName}} |
*ngFor="let item of bookService.GetBookList() | async"; {{item.bookName}}
3. Using take(1)
It makes sure that you’re getting the data only once.
this.bookService.GetBookList() .pipe(take(1)) .subscribe(res = {this.bookList = res;}) |
this.bookService.GetBookList() .pipe(take(1)) .subscribe(res = {this.bookList = res;})
8. Avoid Logic in templates
Even when the function calls in angular templates that are technically correct, all template related business logic can be extracted into a component. It assists in unit testing and also reduces bugs in case of a template change in the future.
9. Cache API calls
Caching API calls improves performance and saves memory by limiting server requests to fetch redundant information. Some API responses may not change frequently so we can put some caching mechanism and can store those values from the API. When the same API request is made, we can get a response from the cache. Thus, it speeds up the application and also makes sure that we are not downloading the same information frequently.
10. Declare Safe Data Types
You will initially have to start by confirming the types of data and the set of values that it holds. After that only the possible values will be accepted by the variable. Instead of declaring a variable of a particular type, we can declare it as a list of possible values or a different type.
Example:
type WeekEnd = "Saturday" | "Sunday"; const day1: WeekEnd = "Saturday"; const day2: WeekEnd = "Sunday"; const day3: WeekEnd = "Monday"; // The last line will give this error: Type ‘"Monday"’ is not assignable to type 'WeekEnd'. |
type WeekEnd = "Saturday" | "Sunday"; const day1: WeekEnd = "Saturday"; const day2: WeekEnd = "Sunday"; const day3: WeekEnd = "Monday"; // The last line will give this error: Type ‘"Monday"’ is not assignable to type 'WeekEnd'.
11. Use CDK Virtual Scroll
CDK(Component Development Kit) Virtual Scroll can be used to display large lists of elements more efficiently. Virtual scrolling enables an efficient way to simulate all values by making the height of the container element equal to the height of the total number of elements.
12. Use Environment Variables
Angular has different environment configurations to declare individual variables for all different types of environments. Development and production are default angular environments. We can even add more environments, or add new variables in existing environment files.
13. Use Lint Rules
The tslint has various inbuilt options like no-any, no-console, no-magic-numbers, etc, which can be configured in tslint.json file. It enforces the program to be decent and more consistent. It can be customized with your own lint rules and configurations. This ensures the readability and consistency of our code.
14. Maintain Proper Folder Structure
Creating and Maintaining a proper folder structure is an important factor everyone should consider before initiating any angular project. The folder structure should be flexible to new changes throughout development.
15. Use Proper Keywords (const vs let)
When you declare a variable if the value is not reassigned “Const” can be used to declare the value. The “let” keyword declares an input variable referenced within the template. Using these keywords makes the declaration of a variable more clear. With this, the code crispness and clarity are improvised with clean code..
16. Avoid having Subscriptions Inside Subscriptions
Technically, nested subscriptions work, but it is not the most effective way. In case, you want the value to be reused in more than one observable then you can use preferrable chaining options like combineLatest, withLatestFrom, etc rather than subscribing one observable in the subscribe block of another observable.
Example:
observable1$.pipe( first(1) ) .subscribe(res1 = { observable2$.pipe( first(1) ) .subscribe(res2 = { console.log(`${res1} ${res2}`); }); }); |
observable1$.pipe( first(1) ) .subscribe(res1 = { observable2$.pipe( first(1) ) .subscribe(res2 = { console.log(`${res1} ${res2}`); }); });
After using withLatestFrom:
observable1$.pipe( withLatestFrom(observable2$), first() ) .subscribe(([res1, res2]) = { console.log(${res1}; ${res2}); }); |
observable1$.pipe( withLatestFrom(observable2$), first() ) .subscribe(([res1, res2]) = { console.log(${res1}; ${res2}); });
After using combineLatest:
combineLatest(observable1$, observable2$).subscribe( ([res1, res2]) = { console.log(`${res1} ${res2}`); } ); |
combineLatest(observable1$, observable2$).subscribe( ([res1, res2]) = { console.log(`${res1} ${res2}`); } );
17. Follow Consistent Angular Coding Best Practices
Here are some Angular coding best practices to follow in order to ensure that your angular development project adheres to the right code standards.
- Files should be limited to 400 lines of code.
- Create short functions with no more than 75 lines of code.
- All symbols should have the same name.
- The pattern feature.type.ts is preferred.
- Declare it with ‘const’ if the variables’ values aren’t changing.
- Separate terms in the descriptive name with dashes, and separate the descriptive name from the type with dots.
- Property and method names should always be written in lowercase.
- When you decide to work in tandem between third-party and applications as well as modules just by leaving one line space in between. For instance, the naming convention for feature module components should be feature.component.ts. The naming convention for new feature modules should be feature.module.ts. The naming standard for feature module services should be feature.service.ts.
18. Break large components into small reusable components.
We can also view it as a Single responsibility development principle. Debugging, managing, and testing large components is difficult. If the component grows in size, split it down into smaller, more reusable components to reduce code duplication and make it easier to manage, maintain, and debug.
19. Declare safe strings
We can define the list of possible values as the type for a variable of type string because it only has a limited set of values. As a result, the variable will only accept the possible values. You can also eliminate the bugs in the code by writing it during compilation time.
Normal String declaration
private dataType: string; // We can assign any string to vehicleType. this.dataType = 'decimal'; this.dataType = 'hexadecimal'; this.dataType = 'xyz'; |
private dataType: string; // We can assign any string to vehicleType. this.dataType = 'decimal'; this.dataType = 'hexadecimal'; this.dataType = 'xyz';
20. Strict string declaration
If you are aware of the data type whether it is decimal or hexadecimal then you must declare it as the data type: Then define the string types as we have demonstrated below
private vehicleType: 'decimal' | 'hexadecimal'; this.vehicleType = 'decimal'; this.vehicleType = 'hexadecimal'; this.vehicleType = 'xyz'; // This will give the below error Type '"xyz"' is not assignable to type '"decimal" | "hexadecimal"' |
private vehicleType: 'decimal' | 'hexadecimal'; this.vehicleType = 'decimal'; this.vehicleType = 'hexadecimal'; this.vehicleType = 'xyz'; // This will give the below error Type '"xyz"' is not assignable to type '"decimal" | "hexadecimal"'
21. State Management
State management is one of the most difficult aspects of software development. Angular’s state management aids in the management of state transitions by storing the state of any type of data.
There are many countless state management libraries for Angular present in the market, such as NGRX, NGXS, Akita, and others, all of which have different uses and objectives. Before we implement our application, we can choose the best state management for it.
Some of the advantages of utilizing state management.
- It allows data to be shared between multiple components.
- It allows for centralized state transition control.
- The code will be cleaner and easier to read.
- It’s simple to troubleshoot when something goes wrong.
- There are development tools that are available for tracing and debugging in state management libraries.
22. Documentation in Code
Documenting code is a good practice. It will assist a new developer in understanding the logic and readability of a project. Documenting each variable and method is a good Angular practice.
Methods must be defined using multi-line comments that indicate what task the method actually does.
/** * This is the get function * @param age This is the age parameter * @returns returns a string version of age */ function getAge(age: number): string { return age.toString(); } |
/** * This is the get function * @param age This is the age parameter * @returns returns a string version of age */ function getAge(age: number): string { return age.toString(); }
23. File Naming
We should pay keen attention to the file names when creating files.
- Folder and file names should be descriptive of their contents.
- The names should follow the same pattern, with the feature of the file coming first, followed by the type, separated by a dot.
For instance, consult.component.ts, home.component.html, and auth.service.ts
If we wish to give our files more descriptive names, we should use a dash (-) to separate the words like this tc-home.component.ts or book-appointment.component.ts.
24. Class Names
In the process of adding names to the classes, it is advisable to use the upper camel case style as a suffix. This will represent the type of file you chooselike TcHomeComponent AuthService MonthDirective and similar class name.
25. Single Responsibility Principle
It is desirable to create separate ts files for components, templates, styles, and services rather than collecting them all together under a single ts file. All the files are responsible for creating a single functionality and if you do that you will be able to create clean, readable, and maintainable code.
26. Using Interfaces
We should always use interfaces when creating a contract for our class. We can force the class to implement functions and attributes declared in the interface by using them. Having angular lifecycle hooks in your component is the finest illustration of this:
OnInit and OnDestroy are implemented by the HomeComponent class.
Interfaces are the right way to describe the defined objects literally.
If an object does not include the interface’s properties, TypeScript will throw an error and turn on IntelliSense for us and start to populate that object:
export interface Student { id: number; name: string; email: string; class: number; gender: "male" | "female"; stream : "science" | "commerce" | "arts"; status: boolean; } |
export interface Student { id: number; name: string; email: string; class: number; gender: "male" | "female"; stream : "science" | "commerce" | "arts"; status: boolean; }
27. Using Immutability
In javascript, the two main reference types are objects and arrays. If we wish to copy them into another object or array and modify them, we should use the es6 spread operator(…) to do so we need to use immutability.
const student = { id: 1, name: "John Doe"; email: "[email protected]"; } |
const student = { id: 1, name: "John Doe"; email: "[email protected]"; }
const results = { ...student, percentage : 90 } |
const results = { ...student, percentage : 90 }
In this way, we’re recreating the user object, and then simply overriding the status property. You can quickly clone user objects and overwrite their status and properties .
28. Change Detection Optimisations.
- If DOM elements aren’t visible, instead of concealing them using CSS, it’s a good idea to remove them from the DOM using *ngIf..
- To make your expressions faster, transfer challenging calculations into the ngDoCheck lifecycle hook.
- Complicated calculations should be cached for as long as feasible.
- To inform Angular that no modifications have occurred, use the OnPush change detection technique. This allows you to skip the whole change detection process.
29. Using Smart – Dumb components / Use Smart – Dumb Components Technique
This technique aids the adoption of the OnPush change detection strategy to inform Angular that the dumb components have not changed. When you are processing the data via API calls, focusing on functionalities, and controlling states, smart components are used. Whereas the dumb components are all about appearances, they are more concerned with how they appear.
Angular Security Best Practices
Nowadays, Angular is the most preferable front-end framework. Majorly it is used in developing web apps all around the globe. Web Security is also important nowadays to protect a site from security attacks and data theft. Here, we discuss some best practices which help us avoid security vulnerabilities in our Angular Best apps.
1. Preventing Cross-Site Scripting
In web applications to prevent malicious attacks, Cross-Site Scripting(XXS) for security vulnerability can be used. This process will send a script to the attacker and the user both at the same time and prevents the user from accepting the malicious script unknowingly into a trusted website.
As the website is trusted, when users open the website that malicious script also executes.
The malicious script that executes on the website may cause a problem as below:
- The DOM tree may be changed by rewriting the HTML page.
- Access information from cookies and sessions.
- Attackers can send their script if the website is not escaping the HTML script Tags.
Cross-Site Scripting (XSS) attack example in a diagram:
1. Prevent client-side XSS attacks
To prevent client-side XSS attacks avoid any modification in the whole DOM tree, because this action may lead to the execution of the malicious script. Use some concept to prevent this type of attack provided by an Angular:
2. InnerHtml property can be used with HTML markups for displaying data:
Angular automatically sanitizes all data that shows in components using the innerHTML property. Using the innerHTML property we can sanitize the server-side response before displaying it on the HTML side.
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrs: ['./app.component.css'] }) export class AppComponent { htmlSnippet = 'Hello, <script>alert("Hi Tatvasoft")</script> <i>Good morning</i>'; } |
import { Component } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrs: ['./app.component.css'] }) export class AppComponent { htmlSnippet = 'Hello, <script>alert("Hi Tatvasoft")</script> <i>Good morning</i>'; }
In the above component, the variable HTML snippet contains HTML data which will be used in the following app.component.html file as a value of ‘innerHTML’ property.
{{htmlSnippet}} div [innerHTML]="htmlSnippet"; |
{{htmlSnippet}} div [innerHTML]="htmlSnippet";
When the above template will be loaded, the page will display like following:
Hello, <script>alert("Hi Tatvasoft")</script> <i>Good morning</i> Hello, Good morning |
Hello, <script>alert("Hi Tatvasoft")</script> <i>Good morning</i> Hello, Good morning
3. Some point which you should note:
- {{htmlSnippet}} contains interpolated data which will be kept as it is. Angular does not modify interpolated content.
- When we assign a variable htmlSnippet to the [innerHtml] property, it will remove the script tag automatically and will display the data as per HTML content. For example, if there is one sentence in bold tag then angular will consider it unsafe and will sanitize that data by removing the scripting tag.
- DOMSanitizer APIs can be used to avoid automatic sanitization:
- As we discussed, angular will sanitize automatically if it found some untrusted data, we can use these types of APIs to prevent automatic sanitization.
- bypassSecurityTrustHtml (By using this we can prevent HTML sanitization):
4. DOMSanitizer APIs can be used to avoid automatic sanitization:
As we discussed, angular will sanitize automatically if it found some untrusted data, we can use these types of APIs to prevent automatic sanitization.
5. bypassSecurityTrustHtml (By using this we can prevent HTML sanitization):
This is the template for the above component:
<div class="container">; {{htmlSnippet}}; p [innerHtml]="trustedHtmlSnippet"; </div>; |
<div class="container">; {{htmlSnippet}}; p [innerHtml]="trustedHtmlSnippet"; </div>;
bypassSecurityTrustUrl (By using this we can prevent URL sanitization):
# Component app.component.ts #import { Component } from '@angular/core'; #import {DomSanitizer} from '@angular/platform-browser'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { htmlSnippet = 'javascript:alert("Hello Tatvasoft!")'; trustedHtmlSnippet; constructor(private sanitizer: DomSanitizer) { this.trustedHtmlSnippet = this.sanitizer.bypassSecurityTrustUrl(this.htmlSnippet); } } |
# Component app.component.ts #import { Component } from '@angular/core'; #import {DomSanitizer} from '@angular/platform-browser'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { htmlSnippet = 'javascript:alert("Hello Tatvasoft!")'; trustedHtmlSnippet; constructor(private sanitizer: DomSanitizer) { this.trustedHtmlSnippet = this.sanitizer.bypassSecurityTrustUrl(this.htmlSnippet); } }
This is how the template looks like:
<div> <a href="htmlSnippet">Click here to Trusted URL</a> </div> |
<div> <a href="htmlSnippet">Click here to Trusted URL</a> </div>
An alert dialog box will get opened when you click the trusted URL link. Clicking untrusted URL, Angular considers that the URL is unsafe.
- bypassSecurityTrustResourceUrl (By using this, we can prevent Resource URL sanitization)
- bypassSecurityTrustScript (By using this we can prevent Script sanitization)
- bypassSecurityTrustStyle (By using this we can prevent Style sanitization)
You must avoid direct use of DOM APIs as Angular recommends usage of templates:
Attackers can inject scripts with the use of ElementRef as Built-in DOM APIs for browsers that do not sanitize data automatically.
import { Component, ElementRef, Renderer2 } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { constructor( private elementRef: ElementRef, private renderer: Renderer2 ) { /*this.elementRef.nativeElement.style.color = 'blue'; // Avoid this.*/ this.renderer.setStyle(this.elementRef.nativeElement, 'color', 'blue'); } } |
import { Component, ElementRef, Renderer2 } from '@angular/core'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent { constructor( private elementRef: ElementRef, private renderer: Renderer2 ) { /*this.elementRef.nativeElement.style.color = 'blue'; // Avoid this.*/ this.renderer.setStyle(this.elementRef.nativeElement, 'color', 'blue'); } }
While loading the component, the alert box will appear on the screen. If we are passing innerHtml variable from bypassSecurityTrustHTML API of DomSanitizer then it will be considered as sanitized.
6. Content security policy (CSP):
In order to prevent XSS attacks, we need to settle policy for content security. The programmer needs to set CSP as part of the HTTP header. Consider the following examples:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';"> <div> |
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';"> <div>
7. Prevent server-side XSS attacks
To avoid Cross-Site Scripting attacks in trusted websites, we need to prevent untrusted script/code allow only clean code, from injecting malicious scripts into the DOM tree.
- At server-side processing, clear all the data which are containing HTML, javascript tags before sending them as the HTTP response.
- You will have to limit yourself from generating Angular templates using server-side processing. This could result in the insertion of the template and thereby there will be DOM manipulation when the page starts loading into the browser.
2. HTTP-related Vulnerabilities
Cross-site request forgery (CSRF or XSRF) and cross-site script inclusion (XSSI) are two types of vulnerabilities where there could be an attack to access data from web apps.
1. CSRF (Cross-site request forgery)
Through this type of vulnerability, attackers make HTTP protocol requests to the server with help of any authenticated user of that site. The attacker works as a hidden mediator in this process.
For example, if an authenticated user is login into his/her website then the attacker will try that user to make an HTTP request by clicking some unknown link and can access secret information from that request.
If the victim user is the administrator of any site then the attacker can access all that information that can be accessed by that administrator.
For avoiding these type of attack, we can use an authentication token with a cookie,
During the HTTP request server will compare token data from the cookie and prevent access data if the token is not authorized.
2. XSSI (Cross-site Script Inclusion)
Attackers are using vulnerable scripts for this method. Don’t use any third-party script which is coming from an untrusted domain, because if it is not secure then the hacker can add any executable code to that script and while executing this script in our domain we might compromise any essential information.
Attackers can also add an API URL through a script tag. Angular has HttpClient library that can help programmers to fetch this type of convention and automatically remove the string “)]}’,\n” from all code and make it non-executable.
3. Use Route Guards on the Navigation
Firstly, we can accept or decline permission to navigate the URL requested by users by working on the route guard interface. Route guards are using a boolean concept like if they all return true value then the user can navigate to the requested URL and if any of them returns a false value then the user will be prevented to navigate that URL.
Different types of route guards:
- CanActivate: Checks whether the component can be accessed or not
- CanActivateChild: Checks whether the child component can be accessed or not
- CanDeactivate: It asks for permission to discard the changes
- CanLoad: Checks before load feature module
- Resolve: It pre-fetch the route data to make sure that data related navigation is available or not.
Route Guard example:
import { Injectable } from '@angular/core'; import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; export class RouteGuard implements CanActivate { constructor(private router: Router) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { // If token is exist, user may login if (localStorage.getItem('token')) { return true; } // otherwise redirect to login page this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } }); return false; } } |
import { Injectable } from '@angular/core'; import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; export class RouteGuard implements CanActivate { constructor(private router: Router) { } canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) { // If token is exist, user may login if (localStorage.getItem('token')) { return true; } // otherwise redirect to login page this.router.navigate(['/login'], { queryParams: { returnUrl: state.url } }); return false; } }
Applying the same route guard in the route of the RouteModule. Following the example code, I have defined the route app.module file.
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { RouteGuard } from './Services/routeGuard' .... @NgModule({ declarations: [ .... ], imports: [ RouterModule.forRoot([ { path: '', component: HomeComponent, pathMatch: 'full', canActivate: [RouteGuard] }, { path: 'my-profile', component: MyProfileComponent, canActivate: [RouteGuard] }, .... ]), .... ], .... }) export class AppModule { } |
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { RouteGuard } from './Services/routeGuard' .... @NgModule({ declarations: [ .... ], imports: [ RouterModule.forRoot([ { path: '', component: HomeComponent, pathMatch: 'full', canActivate: [RouteGuard] }, { path: 'my-profile', component: MyProfileComponent, canActivate: [RouteGuard] }, .... ]), .... ], .... }) export class AppModule { }
Generally, programmers are using logged-in user’s information like name, email, authentication token, etc. we store these pieces of information in local storage or window session storage.
Window session storage is more secure than local storage as it is removing user data when the browser gets close and it will prevent any third-party users (hackers) from accessing user’s data.
Use any storage to maintain data according to your project requirement but make sure that the user’s data must be cleared after the appropriate user gets logged out.
4. Keep Updating Angular Libraries
Angular is getting better day-by-day and providing updates frequently to enrich existing functionality and to give the best performance.
Updates keep coming every now and then with resolved issues and providing good security purposes, so keep updating your libraries and take maximum advantage of the angular framework to keep your systems flexible.
5. Must Avoid Usage of Templates Generated by Concatenating User Input
In most cases, normally we are using string interpolation or the recommended component configuration in an Angular application. But sometimes, there are some requirements that we need to concatenate input string to template.
For example:
import { Component, Input } from '@angular/core'; import { AdvertisementComponent } from './../advertisement/AdvertisementComponent'; const potentialUserInput = <!--user input to the template--> Hello ... @Component({ template: <section> <h2>{{source.title}}</h2> <div>{{source.body}}</div> </section> + potentialUserInput }) export class JobComponent implements AdvertisementComponent { @Input() source: any; } |
import { Component, Input } from '@angular/core'; import { AdvertisementComponent } from './../advertisement/AdvertisementComponent'; const potentialUserInput = <!--user input to the template--> Hello ... @Component({ template: <section> <h2>{{source.title}}</h2> <div>{{source.body}}</div> </section> + potentialUserInput }) export class JobComponent implements AdvertisementComponent { @Input() source: any; }
While using this type of concept you need to filter the user input data to prevent some attack because some attackers can send executable code for accessing information through their input (potentialUserInput) as shown in the above code.
Make your you never extract template source code by performing concatenation of user input and templates. To prevent these vulnerabilities, we can use “template injection” which is an offline mode of template compiler.
If we are using javascript then string concatenation is pretty easy. In Angular, there is an Ahead of Time compiler which compiles templates offline and converts HTML and typescript code into javascript.
ng build --aot ng serve --aot |
ng build --aot ng serve --aot
From Angular – compiling with Ivy ahead of Time compiler is set to true by default which is avoiding template injection.
{ "projects": { "heroes-project": { "architect": { "build": { "options": { ... "aot": true, } } } } } } |
{ "projects": { "heroes-project": { "architect": { "build": { "options": { ... "aot": true, } } } } } }
6. Avoid Making Changes in Angular Core Module Unless Absolutely Necessary
If you are changing or modifying any files of the Angular core module then this may affect the security and you might face some protection issues. Any unsure modification made in the default content of an Angular can harm existing functionalities or can change the default behavior of the current version.
So, if you want to essentially change or fix any existing problem by making pull requests, you should let the Angular community know this and they will update your changes if they do not affect any of the current features.
Key Features of Angular
1. Component-based Architecture
The Angular framework separates the UI of the entire app into independent reusable components. These components follow a hierarchical structure. We can gather elements with similar functionalities, use components directives and convert them into well-defined angular components that can be reused anywhere in the angular project for implementing functionality with similar business logic.
2. Angular Material
Angular Material is a complete UI solution for a compatible UI. It is a complete library of reusable UI components. It consists of several components like buttons, form controls, theming options, data tables, etc.
3. Modular Structure
The modular structure of Angular arranges the code into different modules so all services and components are divided into different groups when you construct them. In angular coding, you can separate functionality into reusable pieces of code.
4. TypeScript
One of the prominent superscripts of JavaScript is Typescript. It has many in-built libraries and provides numerous functionalities to an Angular Application.
5. Angular CLI
Angular CLI(Command Line Interface tool) helps in developing, scaffolding, testing, and deploying angular applications. It can generate a new angular app and files, execute an angular app, run tests, and build angular applications for their deployment.
6. Angular Router
Acquiring all in-built Routing and Navigation features are best practices, Angular applications works best for all businesses. Angular routers navigate from one page to another page without page reload and while routing to the other component it activates other required angular components as well.
7. Angular Universal
Your web apps are more engaging and easy to use because of the usage of Angular Universal. It enables you to render web apps on the server-side which is helpful to any web application especially for improving search engine optimization performance.
Conclusion
Multiple frontend developers are keen to develop innovative and seamless angular apps using their extensive knowledge of frameworks. With this comprehensive blog on the Angular best practices, we tried to cover all the major aspects and best practices that can be used by businesses in their development process and reap maximum benefits from it. Angular framework has empowered the development process with easy code writing, two-way data binding, simpler structure and other essential contributions that makes the task easy. If your in-house business is unable to do this, partner with experts for pioneering app development using the Angular framework.
We have presented an info-graphical representation of Angular Best Practices. Take a look:
Share this Image On Your Site
Please include attribution to TatvaSoft.com with this graphic. <a href="https://www.tatvasoft.com/blog/angular-optimization-and-best-practices/"><img src="https://www.tatvasoft.com/blog/wp-content/uploads/2020/12/Angular-Best-Practices-Infographic.jpg" alt="Angular Best Practices" width="952" height="3948"></a> |
Please include attribution to TatvaSoft.com with this graphic. <a href="https://www.tatvasoft.com/blog/angular-optimization-and-best-practices/"><img src="https://www.tatvasoft.com/blog/wp-content/uploads/2020/12/Angular-Best-Practices-Infographic.jpg" alt="Angular Best Practices" width="952" height="3948"></a>
Other Best Practices Blogs:
Vishal Shah
Vishal Shah has an extensive understanding of multiple application development frameworks and holds an upper hand with newer trends in order to strive and thrive in the dynamic market. He has nurtured his managerial growth in both technical and business aspects and gives his expertise through his blog posts.
Subscribe to our Newsletter
Signup for our newsletter and join 2700+ global business executives and technology experts to receive handpicked industry insights and latest news
Build your Team
Want to Hire Skilled Developers?
One of the best practices that I would like to add to this blog is the Rule of one file per object. According to this rule, the developer should have only one object per file. This also helps in following the single responsibility principle.
One feature that I like the most about Angular is lazy loading, an in-built feature of Angular in which it loads the required components and other required things along with this it stops other non-required files from getting loaded. This helps in the speedy loading of the required data.
In angular or any other programming language, there is a lot of stress laid on coding best practices by the web development companies. By following these angular coding best practices, developers are able to fix the bugs easily and it also helps in creating a better experience for the users.
Angular without a doubt is a powerful framework which is used for developing dynamic applications. Using Angular CLI helps in creating components, directives and much more. Along with this it also helps to build, server and test. Thanks for the input.
Your overall angular application’s efficiency can be improved greatly by breaking bigger components into smaller components such that each has the smallest unit to task to perform.
Looking at the popularity and success that Angular has gotten in recent years it's inevitable for your business to survive without making use of Angular. But as there is a widespread adoption of the technology, it leaves no room for the companies to get a competitive edge over others. But there is one thing that can help you in achieving this and they are these best practices.Thank you.
Can someone let me know which companies are using Angular?
Here is the list of the companies who are using Angular are: 1. Gmail, 2. Forbes, 3. Paypal, 4. Samsung, 5. Upwork, 6. Microsoft Xbox, 7. The Guardian and many more.
I wanted to know what kind of applications can be built using Angular.JS
As we all are aware Angular is an open source language best known for getting regular updates and it also has powerful community support. Coming to the point Angular can be used for building web application, user frontends, PWA or Progressive web apps, Web apps for enterprise, Last but not the least for building Single/one page applications (SPA’s) and many more.
Best practices are something that every developer has to know and implement, almost every single time while starting a new project or optimizing the performance of their Application. Every developer should visit this page for knowing more about Angular.
Best practices are a kind of summary of years of experience and knowledge put together and I must say it is a very detailed and comprehensive blog. Being a learner in Angular, It has helped me a lot.
Yes, Angular is an open-source framework which was introduced by Google that helps developers in creating web apps. AngularJS is a JavaScript-based open-source framework used by development companies to create single-page web applications (SPA’s). In terms of Mobile support, only Angular supports mobile development, not Angular JS. Angular is written in Typescript (Microsoft language) and AngularJS is written in JavaScript.
Are Angular and AngularJS different?
Reasons to choose Angular for front end development are as follows: 1-Developed by Google 2-Capacity to develop Single page Application 3-Components can be reused. 4-Offers a lot of functionality with short codes. 5-Has Outstanding Community Support.
Can any answer my question Why is Angular the best front-end framework?
Actually, I am not very much aware of SEO and how to make a website SEO friendly because my client always asks me to do development-related changes SEO Friendly. This article helps me in some way to do it. Anyways I have also found some other best practices like making use of a Router for navigating from one page to another without page reload,using Angular Universal for making web app SEO friendly.
Thanks for sharing this article, Angular is something new for me, I have found this while searching for Angular Best Practices. It's very nicely written and I learned a lot from this helpful resource.
Thank you mate.
As a novice user of Angular framework and I found one technique of mitigating the risk of cross-site scripting and HTTP-related vulnerabilities is really helpful. I'll send an email to you guys on this subject. I hope that you guys will help. Thanks
I couldn’t leave without commenting on this blog and the special mention is to the infographic presented in the blog. The infographic crisply conveys the best practices and the simpler declaration of each important factor and table that might be helpful in preventing memory leaks in Angular apps.
This blog really helped me in honing my skills as an angular developer. Using Lint rules and Linting packages have just perfected my code. The use of authentication token and 2-factor authentication is one of my favorite practices for end-to-end security.
Thank you for an excellent blog. The information is amazing and interesting. This is a must-read for everyone. I really appreciate your hard work.