Skip to main content

Outputs

Data flow is bidirectionnal. Child components have to notify their parent components when some things happen.

For instance, a rating component could notify its parent component when the rating changes.

To do so, the child component must define an output property.

How to define component outputs?โ€‹

Since Angular 17.3, components can define their output using the output() function.

import { output } from '@angular/core';

@Component({
...
template: `@for (level of levels; track level) {
<mc-rating [rating]="level" (click)="onLevelClick(level)"/>
}`
})
class CookbookPreview {
readonly levels = [1, 2, 3, 4, 5];
readonly ratingChange = output<number>();

protected onLevelClick(level: number) {
this.ratingChange.emit(level);
}
}
tip

For such a simple use case, you can emit the rating directly in the template: (click)="ratingChange.emit(level)".

That said the onLevelClick method makes it easier to add a breakpoint or a log when debugging.

How to listen to child component outputs?โ€‹

Child components outputs are emitted using event binding:

@Component({
template: `<mc-rating (ratingChange)="onratingChange($event)" />`,
})
class CookbookPreview {
onratingChange(rating: number) {
console.log('rating changed', rating);
}
}

How to migrate legacy @Output()?โ€‹

Before output(), components defined their outputs using the @Output() decorator.

@Component({...})
class Rating {
@Output() ratingChange = new EventEmitter<number>();
}
tip

You can automatically migrate your legacy @Output() to output() using the Angular CLI output-migration generator:

nx g @angular/core:output-migration

# or if you are using the Angular CLI
ng g @angular/core:output-migration
Pragmatic Angular Testing
๐Ÿ‘จ๐Ÿปโ€๐Ÿณ Let's cook some tests โ†’

๐Ÿ’ฐ 80โ‚ฌ ยท 170โ‚ฌ ยท Lifetime access

Learn how to write reliable tests that survive upgrades and refactorings.