Angular 16.2 Overview
The Angular team shipped version 16.2, bringing forward two headline capabilities: property bindings for dynamically loaded components, plus a pair of new application-level hooks.
Angular 16.2
Property Bindings for ngComponentOutlet
The ngComponentOutlet directive handles dynamic component loading. Previously, applying property bindings to it was cumbersome, if not outright problematic. That limitation disappears with 16.2, making the workflow significantly smoother.
// Example showing property binding for ngComponentOutlet
@Component({
template: `<ng-container
*ngComponentOutlet="component; inputs: context"
></ng-container>`,
standalone: true,
imports: [NgComponentOutlet],
})
export class AppComponent {
daylightService = inject(DaylightService);
component = this.daylightService.isDay()
? WelcomeAtDayComponent
: WelcomeAtNightComponent;
context: Record<string, unknown> = {};
constructor() {
const { sunrise, sunset } = this.daylightService.getSunTimes();
this.context = {
username: inject(UserService).username,
sunrise, sunset,
};
}
}
afterRender & afterNextRender
These two additions are not component lifecycle hooks in the traditional sense; they operate at the application level.
Instead of implementing interfaces within components, these functions can be invoked from any injection context, most commonly a constructor.
Since they are application hooks, they can be registered from services as well. Angular tracks them globally and executes them in their registration order.
afterRender executes following every change detection cycle, even when no DOM updates occurred. afterNextRender fires only once, also after change detection.
For third-party JavaScript libraries that require DOM access upon initialization, afterNextRender is the go-to choice. On the other hand, afterRender holds more appeal for those developing libraries.
Neither hook runs during server-side rendering.
// Example showing afterRender and afterNextRender
@Component({
template: ` <img
src="https://api.eternal-holidays.net/holiday/darmstadt.jpg"
/>`,
standalone: true,
})
export class AppComponent {
ngZone = inject(NgZone);
cdCounter = 0;
constructor() {
// Count Change Detection Cycles
afterRender(() => {
console.log('CD Runs: ', ++this.cdCounter);
});
// Verify optimised image resolution
afterNextRender(() => {
this.ngZone.runOutsideAngular(() => {
const img: HtmlImageElement =
document.getElementsByTagName('img')[0]
img.addEventListener('load', () => {
if (img.naturalWidth > img.width) {
console.error('Image too large. Use NgOptimizedImage');
}
});
});
});
}
}
Additional Updates
The Angular CLI and Angular Material also received fresh updates. As per usual, Cédric Exbrayat compiled an in-depth blog post detailing every modification, and the official ChangeLog serves as a comprehensive reference for those wanting more.
Fresh Minor Releases
TypeScript 5.2
TypeScript 5.2 hit the shelves, with its marquee feature being "Explicit Resource Management" via the using declaration—a concept familiar to those who know C#'s using or Java's try-with-resources.
Angular 16.2 remains on TypeScript 5.1, as the framework typically waits for a new minor or major release before adopting a fresh TypeScript version.
Playwright 1.37
Beyond that, Playwright received its own minor update. Version 1.37 enhances the UI mode, simplifying network request monitoring. Additionally, multiple reports can now be merged—a crucial capability when Playwright operates in sharded mode.
NgRx 16.2
NgRx, the popular state management library, advanced to 16.2. Alongside various bug fixes, it brought modest enhancements to its ESLint integration and the DevTools extension.
