Table of Contents
- Clean Up Component to Prevent Memory Leak
- Do not Set HTML to Element Directly
- Beware Variable Changes Inside Component
- Use 'trackBy' to Prevent Re-Rendering Same Data
- Use '?' to prevent exception in HTML
- Use 'ng-container' with *ngIf to prevent nested HTML
Components
This page will give you some practices and tips/tricks about Angular components.
Clean Up Component to Prevent Memory Leak
For example, when you create interval
observable
import { interval, Subscription } from 'rxjs';
@Component({...})
export class MyComponent implements OnInit, OnDestroy {
ngOnInit () {
// create interval observable
const source = interval(60000);
source.subscribe(...);
}
}
You should use subsink to remember your observable and call unsubscribe
function when component destroyed.
@Component({...})
export class MyComponent implements OnInit, OnDestroy {
private subs = new SubSink();
ngOnInit () {
const source = interval(60000);
const source2 = interval(30000);
const source3 = interval(10000);
// remember subscription
this.subs.sink = source.subscribe(...);
this.subs.sink = source2.subscribe(...);
this.subs.sink = source3.subscribe(...);
}
// unsubscribed all subscriptions when component is destroyed.
ngOnDestroy() {
this.subs.unsubscribe();
}
}
Note Angular will automatically clean up unsubscribe observable that created from HttpClient
. More information here
Do not Set HTML to Element Directly
To prevent XSS Injections. Angular provides method to set HTML content.
// No
setValue(html: string) {
this.element.nativeElement.innerHTML = html;
}
// Yes
setValue(html: string) {
this.renderer.setElementProperty(
el.nativeElement,
'innerHTML',
html
);
}
// No
setTitle(title: string) {
document.title = title;
}
// Yes
import { Title } from '@angular/platform-browser';
public constructor(private titleService: Title) { }
setTitle(title: string) {
this.titleService.setTitle(title);
}
Beware Variable Changes Inside Component
Sometimes when you get input variable from parent component and change values, the values will have effect to parent too.
class MyComponent {
@Input() items: Int[];
someFunctions() {
// beware that changes will have effect on parent component.
this.items[0] = 1;
}
}
Use 'trackBy' to Prevent Re-Rendering Same Data
trackBy
is the keyword used with ngFor
to tell angular to watch field in item. If that field changes, it will trigger Angular to re-render HTML.
<div *ngFor="let item of list; trackBy:myFunction">
...
</div>
class myComponent {
ngOnInit () {
this.apiService.getSomeData().subscribe((response: any) => {
this.list = response.data;
});
}
myFunction(index, item){
// If item.id changed, angular will re-render item.
return item.id;
}
}
Use '?' to prevent exception in HTML
// Yes
<div>
</div>
// Okay. if you want to hide element when data is null.
<div *ngIf="employee && employee.address && employee.address.city">
</div>
Use 'ng-container' with *ngIf to prevent nested HTML
ng-container
does not create a real element in HTML. It can be used with ngIf
or ngFor
.
// Yes
<ng-container *ngIf="...">
<button> LOGIN.SIGN-IN-ADFS </button>
</ng-container>
// Okay. if you really want to create div in HTML.
<div *ngIf="...">
<button> LOGIN.SIGN-IN-ADFS </button>
</div>