
July 16, 2025 08:41 by
Peter
Component communication is essential for creating reusable and modular components in Angular. Data is often sent from a parent component to a child component using @Input() and returned using @Output() with an EventEmitter.

The Real Issue
One of our projects involved a parent component passing a selected item ID to a child component via @Input(). The child component used that ID to retrieve and show the details. However, when the user quickly picked a different item, the kid did not always display the change. Sometimes it displayed outdated info or didn't update at all.
What Went Wrong
Angular's @Input() only updates when the value changes, but in certain situations (such as when the same ID is passed again after a brief delay), lifecycle hooks like ngOnChanges() failed to detect it. Additionally, ngOnInit() wasn't retriggered on each input change because the child only made one HTTP call.
Solution
We moved the API fetch logic from ngOnInit() to ngOnChanges() and added a proper check for changes:
@Input() itemId!: string;
ngOnChanges(changes: SimpleChanges): void {
if (changes['itemId'] && changes['itemId'].currentValue) {
this.loadItemDetails(changes['itemId'].currentValue);
}
}
loadItemDetails(id: string) {
this.http.get(`/api/items/${id}`).subscribe(res => {
this.itemDetails = res;
});
}
We also added a condition to prevent redundant API calls if the ID hasn’t changed.
Additional Fix
For cases where the same value might be passed again, we manually reset the input before reassigning:
this.selectedItemId = null;
setTimeout(() => this.selectedItemId = item.id, 0);
This trick forces Angular to treat the new input as a different value.
Conclusion
Angular’s @Input() and @Output() work well for component communication, but they don’t always detect subtle changes unless lifecycle hooks are handled properly. Moving logic to ngOnChanges() ensures that child components respond to dynamic data accurately.