Let us list out the most important changes and new features in the minor versions Angular 17.3
New output()
API
Angular 17.3 introduced the new output()
API, for emitting output from a component. This API is designed to complement the input()
and model()
APIs, and it’s type safe.
Official docs: output
@Component({
selector: 'app-output',
standalone: true,
template: `
<button (click)="onClick.emit()">Button</button>
<input #in type="text" (keyup)="onChange.emit(in.value)" />
`,
})
export class OutputComponent {
onClick = output(); // ? OutputEmitterRef<void>
onChange = output<string>(); // ? OutputEmitterRef<string>
}
@Component({
selector: 'app-output-wrapper',
standalone: true,
imports: [OutputComponent],
template: ` <app-output (onClick)="log('onClick')" (onChange)="log('onChange', $event)" /> `,
})
export class OutputWrapperComponent {
log(t1: string, t2: string = '') { console.log(t1, t2); }
}
// after you click on the button, then type 'test' into the input field,
// the messages on the console are:
// onClick
// onChange t
// onChange te
// onChange tes
// onChange test
outputFromObservable()
helper functions
In addition the new output()
API, Angular 17.3 also contains the outputFromObservable()
helper function for transforming an observable to a component’s output()
.
Official docs: outputFromObservable,
@Component({
selector: 'app-output2',
standalone: true,
template: `<button (click)="onClick$.next('click2')">Button</button>`,
})
export class Output2Component {
onClick$ = new BehaviorSubject(''); // ? BehaviorSubject<string>
onClick = outputFromObservable(this.onClick$); // ? OutputRef<string>
}
@Component({
selector: 'app-output-wrapper2',
standalone: true,
imports: [Output2Component],
template: `<app-output2 (onClick)="log('onClick', $event)" />`,
})
export class OutputWrapper2Component {
log(t1: string, t2: string = '') { console.log(t1, t2); }
}
// after you click on the button, the message on the console is:
// onClick click2
outputToObservable()
helper functions
There is also a new outputToObservable()
helper function for converting a component’s output to an observable.
Official docs: outputToObservable
@Component({
selector: 'app-output3',
standalone: true,
template: `<button (click)="onClick.emit()">Button</button>`,
})
export class Output3Component {
onClick = output(); // ? OutputEmitterRef<void>
}
@Component({
selector: 'app-output-wrapper3',
standalone: true,
imports: [Output3Component],
template: `<app-output3/>`, // ? no (onClick)="..." here!
})
export class OutputWrapper3Component implements OnInit {
childComponent = viewChild(Output3Component);
destroyRef = inject(DestroyRef);
ngOnInit(): void {
const childComponent = this.childComponent();
if (childComponent) {
const onClick$ = outputToObservable(childComponent.onClick) // ?
.pipe(takeUntilDestroyed(this.destroyRef));
onClick$.subscribe(() => console.log('onClick'));
}
}
}
// after you click on the button, the message on the console is:
// onClick
Typescript 5.4 support
Daniel Rosenwasser highlighted the most interesting new features of Typescript 5.4 in his announcement:
- Preserved Narrowing in Closures Following Last Assignments
- The
NoInfer
Utility Type Object.groupBy
andMap.groupBy
- Support for
require()
calls in--moduleResolution bundler
and--module preserve
- Checked Import Attributes and Assertions
- Quick Fix for Adding Missing Parameters
- Auto-Import Support for Subpath Imports
Reference:
https://www.angularaddicts.com/