2

I am very undecided whether to use BehaviorSubject to bind data to html. Below are two examples, the First sample binds normally, and the second one binds with "changeDetection: ChangeDetectionStrategy.OnPush" and "BehaviorSubject"

https://stackblitz.com/edit/angular-ivy-gbfqjo?file=src/app/app.component.ts

https://stackblitz.com/edit/angular-ivy-jgnqpt?file=src/app/app.component.ts

As seen in Console , The first method, (ChangeDetection is default and always running), it always calls setName function and logs "init", but in second method, setName is only calls when if $data is registered new value, because of "ChangeDetectionStrategy.OnPush" (dont need ChangeDetectorRef.detectChanges() because data$ already inited).

When should I use method 1 or method 2? Is there an important performance increase?

For example, which method should I use to show 100 data on the table (can be delete from table)?

Which one should I use to lazy load messages (like an infinite scroll)?

When should I use the BehaviorSubject (when just I need Observable) or should I always use it to bind data?

OMANSAK
  • 1,066
  • 1
  • 12
  • 30
  • You should go with the ChangeDetectionStrategy.OnPush strategy, it will improve the performance since it will not run the change detection cycle from parent to child always. If you have large data then go with lazy loading the data. If you want to display some initial messages then use BehaviorSubject. – Amit Vishwakarma Jan 16 '22 at 13:50

2 Answers2

0

First of all, using setName() method in the template is bad practice because it runs in every change detection and creates performance issues. So you can avoid this with Pure pipes. If you use pure pipes and avoid using the method, the first approach is ok and works fine.

But you can use BehaviorSubject inside data services in order to share data in a reactive way between components and other services as well.

But ChangeDetectionStrategy.OnPush helps you to prevent some presentational components to be rendered each time change detection runs. For example, if a data or input changes in a parent component and you have lots of child components that are not affected with this change, you can use this approach to avoid these components to be rendered and increase performance of your app.

Leroy Meijer
  • 1,169
  • 17
  • 40
Mohammad Babaei
  • 473
  • 6
  • 16
0
 public data = [
    { Id: 1, Name: 'A', formatedName: '' },
    { Id: 2, Name: 'B', formatedName: '' },
  ];

  public setName(e: string) {
    console.log('init');
    return e + '-' + e;
  }

  ngOnInit() {
    this.data.map((item) => {
      item.formatedName = this.setName(item.Name);
      return item;
    });
  }

<div *ngFor="let item of data">
  <span [innerText]="item.Id"></span>
  <span>{{ item.formatedName }}</span>
</div>

but the best practice is to use pipe

@Pipe({
  name: 'customName',
})
export class CustomNamePipe implements PipeTransform {
  transform(name: string): string {
    return name + '-' + name;
  }
}


<div *ngFor="let item of data">
  <span [innerText]="item.Id"></span>
  <span>{{ item.Name | customName }}</span>
</div>


https://stackblitz.com/edit/angular-ivy-ssvytn

Souhail HARRATI
  • 303
  • 2
  • 7
  • Thank you for your answer, i know Pipes, so whats it best practice for "getUserName" https://stackblitz.com/edit/angular-ivy-bbw1u3?file=src/app/app.component.ts ? – OMANSAK Jan 16 '22 at 19:16