Every-angular-developer-should-be-familiar-with-these-tips

Every angular developer should be familiar with these tips

AngularJS has become an increasingly popular framework for building web applications. It provides many features that other frameworks don’t offer, and its popularity has grown rapidly in recent years. I listed the most often asked questions and doubts or confusions by angular developers. I’ll go over the top questions that people have and their answers. I have divided them into 2 parts, first one is discussed in this post.

I have researched these and improved my solutions. I wanted to share it with you in this post and let’s start implementation of it from now and make it good practice. So, I’m posting this article to help you in developing better and stronger angular apps and to save you from a lot of performance difficulties.

AngularJS has become an increasingly popular framework for building web applications. It provides many features that other frameworks don’t offer, and its popularity has grown rapidly in recent years.

Create Custom Components with NgModule

AngularJS allows you to use custom components within your application. You can also reuse them across multiple projects. To do so, you need to define a module using the NgModule.forRoot(). This will allow you to import the component into any project.

Build an Angular App Using Webpack

In this tutorial, we will build an Angular app using webpack. We will start by creating a new directory called angular-webpack-starter. Then we will install the dependencies needed to run our app. Next, we will configure webpack to compile our code. Finally, we will add some styles to make our app look nice.

Set up a Continuous Integration System

A continuous integration system (CI) is a software development practice where multiple people work together on the same project at the same time. It helps ensure that everyone is building the same version of the codebase. This means that when one developer makes changes to the code, other developers can see those changes immediately. If you use GitHub as your source control repository, then you can set up a CI pipeline with Jenkins. You can also use Travis CI, Circle CI, AppVeyor, or any other CI service.

Learn About Angular Testing Tools

There are several tools available to help you test your Angular applications. These tools allow you to run tests against your application without having to build it first. They also provide feedback on how well your application works.

Debugging Angular Applications

If you are using Angular CLI, there are some debugging options available. You can use ng serve –open to open an interactive development server. This will open up a browser window with your app running inside of it. You can then make changes to your code and see them reflected immediately. To view errors in your console, you can use ng serve –inspect-brk. This will stop your application when any error occurs. Then you can inspect the error in the Chrome developer tools.

When should we utilize observables instead of promises?

Promises and Observables make it easy for us to deal with asynchronous development.

In angular, Promises provide an easy way to execute asynchronous functions that use callbacks. They represent an eventual result of an asynchronous activity and can return one of 3 states: fulfilled, pending, and rejected.

On the other hand, Observable is a function that converts the ordinary stream of data into an observable stream of data. Observable emits the value from the stream asynchronously. Observable starts to emit values only when someone subscribes to it.

First of all, we should understand the difference between promises and observables.

The main key differences are:

While observables emit numerous values over time, promises can only emit a single value at a time.

In order to avoid memory leak problems and improve efficiency, promises cannot be canceled after being used, although observables can be canceled after being used with unsubscribe().

While observables behave lazily and are not called until we subscribe to them, promises can call the service API even if we do not use them ().

Many rxjs operators can be used with observables to simplify and transform processes, retry, filter, and use utility operators. These operators provide us with the ability to improve the performance of our app.

We can utilize any of them depending on the differences and our development needs.

Why should we unsubscribe to all subscriptions after their use?

In angular, When we subscribe to any observable, we should unsubscribe after its use otherwise it’ll stay somewhere beyond the usual or expected time and it would cause memory leaks at runtime.

We should always unsubscribe to observables after their use, we can unsubscribe them in many ways, one of which is unsubscribing observables on ngOnDestroy() like the below example.

subs: Subscription = new Subscription();

getAllPosts(){
this.subs.add(this.dataService.getPosts().subscribe(posts => {
this.posts = posts;
console.log('posts: ', posts);
}));
}

ngOnDestroy(): void {
this.subs.unsubscribe();
}

When do we need to use an async pipe?

The async pipe allows us to subscribe to a Promise or Observable from the template side and it will return emitted values.

When the template loads, the async pipe subscribes observable automatically, and it unsubscribes when the template is destroyed.

The async pipe automatically subscribes and more important unsubscribes automatically so problems with memory leaks won’t arise throughout the async pipes.

Let’s see with the examples:

Async pipe with Promises:
Suppose we have to execute promises and set values inside then() statement.



// typescript side
export class TestComponent implements OnInit {
promise?: string;

ngOnInit(){
this.getPromise().then(value => this.promise = value);
}

getPromise(): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("My Promise is completed."), 2000);
});
}
}

//template side
<div>
<h1>Async Pipe</h1>
<p>{{ promise }}</p>
</div>

Let’s see an example with an async pipe easy to execute promises.

// typescript side
export class TestComponent implements OnInit {
promise?: Promise<string>;

ngOnInit(){
this.promise = this.getPromise();
}

getPromise(): Promise<string> {
return new Promise((resolve, reject) => {
setTimeout(() => resolve("My Promise is completed."), 2000);
});
}

//template side
<div>
<h1>Async Pipe</h1>
<p>{{ promise | async}}</p>
</div>

Here we executed promises without then() using async pipe.

Async pipe with Observable:
Suppose we have to subscribe to an observable method and access the value and display it.

export class TestComponent implements OnInit, OnDestroy {
obsValue?: string;
subs?: Subscription = new Subscription();

ngOnInit(){
this.subs?.add(this.getObservable()
.subscribe(value => this.obsValue = value));
}

getObservable(): Observable<string> {
return new Observable((observer) => {
setTimeout(() => {
observer.next("observable emitted")
}, 1000);
})
}

ngOnDestroy(): void {
this.subs?.unsubscribe();
}
}

// template side
<div>
<h1>Async Pipe</h1>
<p>{{ obsValue }}</p>
</div>

Here we have to subscribe and unsubscribe manually, Sometimes we neglect to unsubscribe, which results in memory leak issues.

If we are using async pipes, they automatically subscribe during component loading and unsubscribe during component unloading.

export class TestComponent implements OnInit {

obsValue?: Observable<string>;

ngOnInit(){
this.obsValue = new Observable((observer) => {
setTimeout(() => { observer.next("observable emitted") }, 1000);
})
}
}


//template side
<div>
<h1>Async Pipe</h1>
<p>{{ obsValue | async}}</p>
</div>

What is ChangeDetectorRef?

It is a base class that provides change detection functionality. The change-detection tree compiles all views that need to change.

abstract class ChangeDetectorRef {
abstract markForCheck(): void
abstract detach(): void
abstract detectChanges(): void
abstract checkNoChanges(): void
abstract reattach(): void
}

Use these methods to add and remove views from the tree, initiate change detection, and explicitly mark views as dirty, which means they have changed and need to be re-rendered.

In angular, there are 2 types of change detection strategies to keep the HTML template and internal model state in sync: Default and OnPush.

Default: It uses the CheckAlways strategy in which change detection is automatic until explicitly deactivated. It is checked continuously also in case we do not require change detection and it is the reason for low performance. This is the default strategy.

OnPush: It uses the CheckOnce strategy, in this strategy automatic change detection is deactivated until reactivated by setting the strategy to Default. Here, we have to invoke it explicitly to change detection. It’ll reduce the change detection cycle and finally improve the performance of the app.

We can update the strategy like this example:

@Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./test.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
})

When to use ngTemplateOutlet?

ngTemplateOutlet is a structural directive in angular. It is used to create and load templates dynamically and also accept context objects as parameters from another section of DOM.

ngTemplateOutlet is used to define a template piece once and use it multiple times and swap those templates as per user interactions in the same template.

Let’s see a simple example:
Suppose I have one sub-template (a piece of HTML code) and need to use the sub-template more than once in the same template. I’ll create a sub-template once and use it multiple times.

<ng-template let-value="data" let-name #testtemplate>
<p>My name is {{name}} and value is {{value}}</p>
</ng-template>

<!-- example-1 -->
<ng-container *ngTemplateOutlet="testtemplate">
</ng-container>

<!-- example-2 -->
<ng-container *ngTemplateOutlet="testtemplate context:{data: title}">
</ng-container>

<!-- example-3 -->
<ng-container [ngTemplateOutlet]="testtemplate"
[ngTemplateOutletContext]="{data: 10}">
</ng-container>

<!-- example-4 -->
<ng-container [ngTemplateOutlet]="testtemplate"
[ngTemplateOutletContext]="{$implicit: 'Alex', data: '10'}">
</ng-container>

Output:

I have used the same sub-template 4 times using ngTemplateOutlet with dynamic and default data passing.

We use context and ngTemplateOutletContext to send dynamic/static details into sub-template in example-2-3.

$implicit is used to send default data like example-4.

As we can see, we can pass static/dynamic details like examples 2-3-4 and we can also set default data using $implcit like example-4.

We can also pass the template into the child component using ng-content and ViewChilds.

Why should we avoid any?

In angular, we should always use type while declaring variables rather than any. Avoiding any type can decrease the number of unexpected problems and will make application refactoring straightforward.

When we declare variables without typing in typescript, it’ll automatically set type as any. We can easily set any type of data into variables but this can cause unexpected problems.
Let’s take an example:

Here if we set the proper type, it’ll provide a compile-time error and we can put our proper value.

Having solid typing in your application also makes refactoring safer and easier. Let’s see an example.

ngOnInit(){

let person = {
name: 'My Name',
age: 30,
add: 'My Address'
}

this.showPerson(person);
}

showPerson(person: any){
console.log(`Name: ${person.name},
Age: ${person.age},
Address: ${person.add}`);
}

Suppose we got the requirement to change property name and address in person.

change property name and address

It’s not returning any error in showPerson() after changing the property in a person object whereas we will get undefined in add property.

If we have proper typing for the person then It’ll return a proper compile-time error and we can get our expected output for the person.

//Person Model
interface Person{
name: string,
age: number,
address: string
}

proper typing

Now we can update where we need to update properties and go for our expected output.

ngOnInit(){

let person: Person = {
name: 'My Name',
age: 30,
address: 'My Address'
}

this.showPerson(person);
}

showPerson(person: Person){
console.log(`Name: ${person.name},
Age: ${person.age},
Address: ${person.address}`);
}

When should we use a reactive form and when a template-driven form?

In angular application, there are 2 types of forms we can utilize. I’ll go through which form is suitable for use, and when to use it.

Use template-driven form(TDF):
When we are updating/migrating our application angular js to angular 2+ application, template-driven form supports ngModel for bidirectional data binding just like the AngularJs ng-model directive.
When we have scenarios to use small forms with low validations, in complex and extensive forms it’s not good practice to put our maximum code/logic on the template side.

Use reactive form(RF):
When the form is extensive and complex, we have to put minimum code on the template side and put maximum logic in the component class for good practice and cleaner code.

In the case of dynamic nested form, the reactive form will be best to develop code and maintain code from both the template and component class side.

Here we will also check the key difference between template-driven form and reactive form:

In template-driven form, a major part of code exists on the template side whereas In the reactive form major logic and validation part is existing on the component class side so here we can see a clean template.

Template-driven forms need the FormsModule, while reactive forms need the ReactiveFormsModule register in their required module.

We can set reactive forms to be a better default choice for new applications.

Generally, reactive forms are easier to use and support better use cases via their observable-based API.

For these reasons, the reactive form works better than the template-driven form.

But it’s still possible to use both forms together if for some reason we really need to.

We can make a choice based on these differences and our needs.

When to use Angular Purposes?

In angular, there are different purposes to use <ng-template>, <ng-container> and <ng-content>. Let’s see them one by one:

<ng-template> is used to set of sub-templates (HTML codes) that will dynamically render
We can also refer to content not directly rendered, but inserted in our template section elsewhere.
We are using structural directives with <ng-template> like *ngIf, *ngFor and *ngSwitch. structural directives are helping decide when to render template contents into DOM.

<ng-container> is used as a container that has not yet been rendered in order to avoid unnecessary <span> and <div>. Sometimes we are adding extra <div> or <span> for *ngIf or *ngFor instead this we can use <ng-container>. When both structural directives (*ngIf and *ngFor) are required at the same Html element but cannot be placed in the same Html element, here we can use <ng-container> as an example.

<ng-container *ngFor="let item of [1,2,3,4,5]">
<div>{{item}}</div>
</ng-container>

<ng-container *ngIf="title">
<ng-container *ngFor="let item of [1,2,3,4,5]">
<div>{{item}}</div>
</ng-container>
</ng-container>

<ng-content> is used to put external content into components this process is known as content projection.
We can pass data into child components using the @Input decorator, but we cannot pass HTML elements. So, we have to use <ng-content> to pass HTML content to child components.

We can also pass multiple HTML contents into child components using <ng-content>.

Your thoughts?

I hope you have enjoyed these tips. I will share the second part of this post soon. I’d want to know what my blog’s readers think. I always appreciate your thoughtful comments, questions, and feedback on this post.

0 replies

Leave a Reply

Want to join the discussion?
Feel free to contribute!

Leave a Reply