I've implemented a child component to render a table based on a list provided via @Input(). The data is loaded via http, however the UI (child component) is not updated unless I wave my mouse over the screen. I've seen people post about implementing ngOnChanges() in my child, but I thought Angular was supposed to do this by default? Am I missing something? Why would the UI not update with this?
Child code looks something like this:
child.component.ts
@Component({
selector: 'child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.scss'],
})
export class ChildComponent implements {
@Input() data: any[] = [];
constructor() {}
}
child.component.html
<table>
<tr *ngFor="let item of data"><td>{{ item }}</td></tr>
</table>
Parent code that uses the component looks something like this:
parent.component.ts
@Component({
selector: 'parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.scss'],
})
export class ParentComponent implements OnInit {
data: string[] = [];
constructor(private endpointService: EndpointService) {}
ngOnInit() {
// response is a string array like: ['hello', 'world']
this.endpointService.loadData().subscribe((response) => {
this.data = response;
});
}
}
parent.component.html
<child [data]="data"></child>
============================= EDIT ==================================
I verified that it only fails to load when updating inside of the subscribe callback (if I set a static array, it loads just fine).
So it looks like I'm able to resolve this by running changeDetectorRef.detectChanges() in the parent component, but this feels hackish like I shouldn't have to do this. Is this a good way to resolve this? Or does this indicate something wrong with my implementation?
parent.component.ts
@Component({
selector: 'parent',
templateUrl: './parent.component.html',
styleUrls: ['./parent.component.scss'],
})
export class ParentComponent implements OnInit {
data: string[] = [];
constructor(private endpointService: EndpointService,
private changeDetectorRef: ChangeDetectorRef) {}
ngOnInit() {
// response is a string array like: ['hello', 'world']
this.endpointService.loadData().subscribe((response) => {
this.data = response;
this.changeDetectorRef.detectChanges();
});
}
}