Angular's Exciting Journey: From v14 to v17 and Beyond
Written on
Hello there!
A multitude of developments in the latest Angular versions has left many developers astonished. With the remarkable features anticipated in version 17, we are witnessing a renaissance in Angular!
This article compiles the most notable advancements made by Angular from version 14 to the soon-to-be-released version 17.
Angular at Version 14
Standalone Components (Developer Preview)
One of the most thrilling features that completely transforms Angular's architecture. It moves from a module-centric application, where components had to be declared within a module for usage, to a completely component-oriented framework. This represents a significant initial step in that direction. An example of this feature will be discussed in the "Angular at Version 15" section.
Typed Forms
This feature tackles the primary issue reported on Angular’s GitHub repository. With typed forms, we benefit from enhanced type-checking for templates. Errors are identified at compile time, unlike before when issues surfaced only during runtime.
And just like any other typed variable, code editors will now offer autocompletion when accessing form properties, isn’t that fantastic?
Inject()
This is an API I utilize daily within my applications. It offers numerous benefits.
- For example, I can declare my observable at the point of declaration (e.g., teams: Observable<Team[]> = inject(TeamsService.getTeams();), which was previously impossible as the declaration had to occur before the constructor.
- In cases where using a constructor is not feasible, such as in functional guards (a new feature simplifying guard usage in Angular available in v15).
Note: inject() can only be invoked from an injection context, like a constructor, factory function, field initializer, or a function utilized with `runInInjectionContext`.
All CommonModule Pipes and Directives Marked as Standalone
This further unlocks the vast potential of the standalone feature. Previously, to utilize the date pipe, for instance, we had to import the CommonModule, which included not just the necessary pipe but also other directives and pipes. Now, these can be imported individually as standalone entities based on specific requirements.
Setting Inputs on ComponentRef using the New setInput() Method
Fantastic news for dynamic components: the new setInput() method allows for a more intuitive and elegant way to set component inputs.
CanMatch Guard for Routes
A new route guard that permits the exclusion of a route during the navigation matching process.
The CanLoad guard determines if code should be downloaded, while canActivate checks if a route should be activated. The canMatch guard allows for routing decisions based on specific data. You can define multiple routes with the same path and activate or load them under certain conditions, such as the user's identity.
NgOptimizedImage Directive (Dev Preview) (14.2)
This is excellent news for applications that load numerous images, like e-commerce platforms. This directive significantly enhances performance and is available as a standalone directive!
With it, you can select between lazy or eager loading modes for images, prioritize them, and set parameters like width, height, fill, etc.
Here is a great article detailing everything you need to know about this directive!
createComponent and reflectComponentType APIs (14.2)
These APIs replace the deprecated ComponentFactory API, making dynamic component creation much simpler.
New APIs for Using Router without RouterModule (Dev Preview) (14.2)
No longer is it necessary to use RouterModule for Router setup. This is a step toward a fully standalone component application. However, using these APIs doesn’t require an application to employ standalone APIs. They allow for more tree-shakable Router features, importing only what is needed.
Angular at Version 15
Standalone APIs (Stable and Production Ready) + Schematics + HTTP/Router APIs
In v15, developers can create a complete standalone Angular application without NgModule.
Enhanced Stack Traces in Browser Console
For developer experience, improvements in debugging and tools are always appreciated!
Hiding CLI Config Files by Default
Visually, this is a significant enhancement — cleaner and less cluttered. However, it caused confusion, especially concerning environment configuration files, which many projects rely on.
Self-closing Component Tags (15.1)
Adds elegance to Angular templates. Note that for projected content, a closing tag is still required.
Add TestBed.runInInjectionContext for Testing Functions that Use inject API (15.1)
If you are utilizing a functional-based resolver guard that injects a service to fetch data, testing this function requires running it in an injection context. This feature enables you to do just that.
New Schematics for Generating Functional Router Guards and Resolvers (15.1)
Guard and Resolver schematics now support a --functional flag. The guard type can also be specified with the --guard-type option.
ng generate guard my-guard --functional ng generate guard my-guard --functional --guard-type canDeactivate ng generate resolver resolve-data --functional
Generate Functional Interceptors as Well
ng generate interceptor my-interceptor --functional
Generate Environment or Config Files (15.1)
The removal of environment and config files by default starting from v15 was not well received. The Angular team has provided schematics for generating these files as needed.
- Generates empty environment files for each project configuration
- Adds a fileReplacement option for each file
# Env files ng generate environments [--project name] # Config files ng generate config [karma|browserslist]
Support for Inline Component Sass Styles with Esbuild Builder (15.1)
From v15.1, you can use Sass (scss or sass) syntax with inline component styles.
Add withNavigationErrorHandler Feature to provideRouter (15.2)
This replaces the errorHandler option in RouterModule.forRoot. Additionally, it operates within an injection context, allowing for the use of inject() to retrieve dependencies.
New Schematic for Converting to Standalone (15.2)
ng generate @angular/core:standalone
Directive Composition API
This powerful API allows you to incorporate behaviors from other directives (including Angular CDK) and apply them to the host element of your component or directive.
Angular at Version 16
EsBuild + Vite (Dev Preview)
This represents a significant shift in Angular application building. The new bundler is incredibly fast and could greatly reduce build times. Experimental support for ng build with esbuild is already available, and improvements to the Development Server have been made (currently in dev preview).
Signals (Dev Preview)
The initial step towards a new reactivity model and zoneless applications for Angular, leading to substantial performance and developer experience enhancements.
- signal() — reactive values
- computed() — reactive values derived from other signals
- effect() — executes code when reactive values change
Here’s a quick guide to getting started with Signals:
Hydration (Documentation Pending)
Enhancing user experience with non-destructive hydration support. Once the browser receives and parses the rendered markup from the server as a DOM, Angular will navigate the structure, add event listeners, and create internal data structures, making the application interactive without requiring a re-rendering process. This resolves the flicker issue with Angular Universal.
Required Inputs
Inputs can now be designated as required. If not set, required inputs will raise an error during compilation. This eliminates the need for manual checks in ngOnChange, making it more intuitive and elegant!
Transform Inputs
For those looking to effortlessly transform data passed into component inputs.
Routing Data as Component Inputs
A fantastic new feature! You can now directly map route data (params, query params, resolved data) to component inputs.
Note: This feature must be enabled in the `provideRouter`.
takeUntilDestroyed & DestroyRef
A versatile way to execute instructions in ngOnDestroy without implementing the lifecycle hook. This works across components, directives, pipes, and DI services, with DestroyRef offering an alternative for registering onDestroy lifecycle callbacks.
Note: `takeUntilDestroyed` needs to be called within an injection context (like `inject()`). Otherwise, you must manually pass the `destroyRef`.
Jest Support (Experimental)
Jest is a popular testing framework, and the Angular team has decided to integrate it. To enable it, adjustments in the angular.json file are necessary.
mapToCanActivate Helper Function
This simplifies the migration to functional guards at the route definition, offering better support for authoring class-based guards if desired.
ngComponentOutlet Now Has Inputs
A new method to pass data to dynamically created components using the ngComponentOutlet directive! There’s no need to use the injector for data passing unless dependencies are necessary.
provideServerRendering Function
This function enables server rendering capabilities for an application.
provideServiceWorker Function
You no longer need a NgModule to enable ServiceWorker in your application. The API is similar to the existing ServiceWorkerModule.register method, making migration easier.
Standalone Support in Angular CLI Schematics
You can now start with a completely standalone app immediately.
ng new --standalone ng generate application --standalone
Angular at Version 17 (Coming Soon!)
This serves as a teaser for the upcoming v17. Stay tuned for a dedicated article upon its release!
New Built-in Flow Control
I previously mentioned the anticipated Angular built-in control flow and its RFC. This is now becoming a reality, and you’ll soon be able to experiment with it (you can even take a shortcut by installing v17.0.0-next.8!). The RFC initially proposed the hash (#) syntax, but adjustments have been made based on community feedback. The same applies to the syntax for the defer feature.
Once you experience it, you’ll appreciate its beauty and power!
Deferred Loading
Introducing lazy loading within a template via the @defer feature. This will revolutionize template construction in Angular, allowing for more than just basic lazy loading. You can define conditions (on interaction, hover, or other events) for when loading should occur.
The @defer can also be integrated with other blocks like @error, @loading, etc.
And much more is on the way!
> More detailed insights into the upcoming version’s new features will be provided in a dedicated article — stay tuned!
That’s all for today; see you next time!
If you have any questions or feedback, feel free to comment or reach out via LinkedIn — I’m always open to discussion!
Want to buy me a coffee? ?
If you enjoyed my article, consider subscribing for my latest posts. If you’re interested in exploring Medium yourself, please support me and countless other writers by signing up for a membership. It costs just $5 per month, supports writers, and gives you the opportunity to monetize your writing. Of course, you can cancel anytime. By signing up through this link, you’ll directly support me, and it won’t cost you anything extra. Thank you immensely!
Let’s connect on Medium, LinkedIn, Facebook, Instagram, YouTube, or Twitter.