I have reproduced a simple stackblitz demonstrating the issue I have been having. The problem is that I have a parent component that passes a boolean to a child component. This boolean is an @Input on the child component. It is important to note that the parent component uses ChangeDetectionStrategy.OnPush. The child component does not have this explicitly set.
When the parent component changes the boolean input property of the child component within a subscribe method, the child component does not initially detect the change. It always take 2 clicks to have the child component detect the change.
However, when I change the boolean input propery of the child component outside of a subscribe method, the child component that properly detects the change, and everything works as expected (1 click for child component to recognize change).
App.Component.ts (Parent Component)
@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ],
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class AppComponent {
constructor(private http: HttpClient) {
}
public isHelloVisible: boolean;
public useHttpGet: boolean;
showHello() {
if (this.useHttpGet) {
this.http.get('https://cors-anywhere.herokuapp.com/https://api.darksky.net/forecast/cc0e3799790b0b34bdeb6fef28c3daf7/17.447409200000003,-78.3724573?units=si').subscribe(data => {
this.isHelloVisible = true;
});
} else {
this.isHelloVisible = true;
}
}
closeHello() {
this.isHelloVisible = false;
}
Child Component (Hello.component.ts)
@Component({
selector: 'hello',
template: `<div *ngIf="showHello">
Hello
<div (click)="closeHello()">Click me to close Hello</div>
</div>
`,
styles: []
})
export class HelloComponent {
@Input() showHello: boolean;
@Output() close: EventEmitter<any> = new EventEmitter();
ngOnChanges(changes: SimpleChanges): void {
console.log(this.showHello);
}
closeHello() {
this.close.emit(null);
}
if useHttpGet is true it does not work and if false everything works.
I realize there may be different ways to do this or manually trigger change detection, but I am more interested in why this does not work, as this does not make any sense to me.
Probably the best way to see this in action is to follow the stackblitz demo.