Angular is the most powerful framework for building dynamic programming structures. It has a wide spectrum of platforms for designing single-page applications. HTML, CSS, and Typescript which is a superscript of javascript frameworks and is used for developing Angular applications. By using Angular technology, we can create more compatible UI applications.

Table of Contents

  1. What are the Features of Angular?
  2. Best Practices of Angular Development
  3. Angular Security Best Practices
  4. Conclusion

What are the Features of Angular?

What are the Features of Angular

1. Component-based Architecture

The Angular framework separates the UI 0.3230.of the entire application into independent components. These components follow a hierarchical structure. We can gather elements with similar functionalities and convert them into well-defined components that can be reused anywhere in the project.

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. 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) helps in developing, scaffolding, testing, and deploying angular applications. It can generate a new angular application and files, execute an angular application, run tests and build applications for their deployment.

6. Angular Router

Acquiring all in-built Routing and Navigation features, Angular 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 application is more engaging and easy to use because of the usage of Angular Universal. It enables you to render web applications on the server-side which is helpful to any web application especially for improving search engine optimization performance.

Best Practices of Angular Development

Best Practices of Angular Development
Give image credit to Tatvasoft.com if you would like to refer this image

1. 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.

2. 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;
}

In component.html file:

<tr *ngFor='let book of books; trackBy:trackByBookCode'>

3. 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 loading all NgModules so it can be useful while loading the large application.
We can use lazy loading by loadChildren instead of loading the component in AppRoutingModule routes configuration.

const routes: Routes = [
  {
    path: 'profile',
    loadChildren: () =&gt; import('./modules/profile/profile.module').then(m =&gt; m.ProfileModule)
  }
];

4. Use Index.ts

Working with the index.js 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';

Now we can import all the files using

import { Test, TestService } from '../test';

5. Avoid ‘any’ type

Avoiding using any ‘type’ which has the possibility to 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.

6. 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 this by following tips,

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 =&gt; {this.bookList = res;});
...
...
ngOnDestroy() {
  this.ngUnsubscribe.next();
  this.ngUnsubscribe.complete();
}

Using the Async pipe

It subscribes to an Observable or Promise and returns to the recent emitted value.

 <li *ngFor="let item of bookService.GetBookList() | async">
{{item.bookName}}
</li>

Using take(1)

It makes sure that you’re getting the data only once.

this.bookService.GetBookList()
      .pipe(take(1))
      .subscribe(res =&gt; {this.bookList = res;})

7. Avoid Logic in templates

Even when a function calls in angular templates that are technically correct, all template 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.

8. 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.

9. 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'.

10. 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.

11. 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.

12. 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.

13. Maintain Proper Folder Structure

Creating and Maintaining a proper folder structure is an important factor everyone should consider before initiating any project. The folder structure should be flexible to new changes throughout development.

14. 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.

15. 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 =&gt; {
    observable2$.pipe(
        first(1)
    )
    .subscribe(res2 =&gt; {
        console.log(`${res1} &amp; ${res2}`);
    });
});

After using withLatestFrom:

observable1$.pipe(
    withLatestFrom(observable2$),
    first()
)
.subscribe(([res1, res2]) =&gt; {
    console.log(`${res1} &amp; ${res2}`);
});

After using combineLatest:

combineLatest(observable1$, observable2$).subscribe(
  ([res1, res2]) =&gt; {
    console.log(`${res1} &amp; ${res2}`);
  }
);

Angular Security Best Practices

Angular Security Best Practices

Nowadays, Angular is the most preferable Javascript framework. Web apps are developed majorly using angular technology. Web Security is also important nowadays to protect a site from security attacks and data theft. Here, we discuss some ways which help us avoid security vulnerabilities in our Angular application.

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:
Cross-Site Scripting (XSS) attack Angular

Prevent client-side XSS attacks

To prevent client-side XSS attacks avoid any modification in the DOM tree, Cause this action may lead to the execution of the malicious script. Use some concept to prevent this type of attack provided by an Angular:

1. 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>';
}

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.

<div>
<div>{{htmlSnippet}}</div>
<br />
<div [innerHTML]="htmlSnippet"></div>
</div>

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

2. 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):

This is the template for the above component:

<div class="container">
<p>{{htmlSnippet}}</p>
<p [innerHtml]="trustedHtmlSnippet"></p>
</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);
 }
}

This is how the template looks like:

<div>
<a [href]="htmlSnippet">Click here to Untrusted URL</a>
<br>
<a [href]="trustedHtmlSnippet">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');
  }
}

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.

Content security policy (CSP):
In order to prevent XSS attacks, we need to settle a 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';">

Prevent server-side XSS attacks

To avoid Cross-Site Scripting attacks in trusted websites, we need to prevent untrusted script/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.

The attacker can access all that information similar to an administrator if the victim has all rights of an administrator of the site.

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 follow boolean concepts to return a true value and navigate to a specific URL. In case if any of them returns a false value then they will be prevented from navigating a specific 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;
 }
}

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 { }

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.

Storage data can be of any type as per the project requirement but once the appropriate user logs out all other used data must be cleared.

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;
}

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

Set Ivy head of Time compiler from Angular to true which will ignore template injection.

{
  "projects": {
    "heroes-project": {
      "architect": {
        "build": {
          "options": {
            ...
            "aot": true,
          }
        }
      }
    }
  }
}

6. You Must Avoid the Change in Default Angular Copy

If you are changing or modifying any in-built content of Angular then this can 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.

Conclusion

Multiple frontend developers are keen to develop Innovative and seamless apps using their extensive knowledge of frameworks. This comprehensive blog on Angular framework showcases all the major aspects essential for development and provides best practices for businesses to reap maximum benefits. 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 Angular framework.

Related Service

Know More About Our Angular Development Services

Learn More

Want to Hire Skilled Developers


    Comments

    • Leave a message...

      1. Kevin Bell

        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.

    Related Articles
    Offshore Outsourcing: Let’s Get Started with Software Development
    Jan 12, 2021
    How do I Integrate CRM into Twilio Flex?
    Dec 2, 2020
    What are ORMs and How does it work?
    Nov 24, 2020