When using
changeDetection: ChangeDetectionStrategy.OnPush, you need to call changeDetectorRef.markForCheck(). To avoid explicitly calling markForCheck, use async pipe on the observable variable. See line 13 on HTML below
@Component({
selector: 'app-contact-us',
changeDetection: ChangeDetectionStrategy.OnPush,
imports: [JsonPipe, CommonModule, FormsModule, JsonPipe],
templateUrl: './contact-us.html',
styles: ``,
})
export class ContactUs implements OnInit {
weather: any = null;
weatherToo: any = null;
weather$: any = null;
weatherToo$: any = null;
// not working
// @Inject(ChangeDetectorRef) private readonly cdr!: ChangeDetectorRef;
// working, but the obvious benefits are still not clear
// private readonly cdr = inject(ChangeDetectorRef);
constructor(private http: HttpClient, private cdr: ChangeDetectorRef) {}
ngOnInit(): void {
this.http.get('/api/WeatherForecast').subscribe({
next: value => {
// console.log({value});
this.weather = value;
this.cdr.markForCheck(); // will reflect on the UI
// use this when you need it be immediate, like in setTimeout or 3rd party library
// this.cdr.detectChanges();
},
error: (err) => console.error('http error', err)
});
firstValueFrom(this.http.get('/api/WeatherForecast')).then(value => {
this.weatherToo = value;
this.cdr.markForCheck();
});
this.weather$ = this.http.get('/api/WeatherForecast');
// this.weather$.subscribe({
// next: (value: any) => {
// console.log('see', {value});
// },
// error: (err: any) => console.error('http error', err)
// });
this.weatherToo$ = this.http.get('/api/WeatherForecast');
}
}
<div>
<hr/>
This works:<br/>
{{weather | json}}
<hr/>
This too:<br/>
{{weatherToo | json}}
<hr/>
This too, and it implicitly calls changeDetectorRef.markForCheck():<br/>
{{weather$ | async | json}}
<hr/>
This will not show null:<br/>
<ng-container *ngIf="weatherToo$ | async as weatherWhenHaveValue">{{ weatherWhenHaveValue | json }}</ng-container>
<hr/>
<input [(ngModel)]="name" placeholder="Name"/>
</div>
Ask this on Gemini or ChatGPT and see the
answer:
does this recommendation kinda defeat the purpose of optimization for when change detection should take effect?
Option 3: Use AsyncPipe in the template
This forces Angular to update on observable emissions, even in OnPush:
weather$ = this.http.get('/api/WeatherForecast');
{{ weather$ | json }}
No comments:
Post a Comment