## The most outstanding features from v14 to v17⚡️
Hi there 👋
A lot of things happened in the Angular latest versions that surprised a lot of developers. And with the upcoming incredible features in Angular version 17, It’s the renaissance of Angular!
This article gathers the most remarkable steps walked so far by Angular from v 14 to the upcoming v17.
## 📌At its 14
**💡 Standalone components (dev prev)**
This is one of the exciting features that completely change the Angular structure. It shifts from a module-based app, where components must be declared in a module to be used, to a fully component-based app. This marks the initial step in that direction. An example demonstrating this feature is provided in the “At its 15” section.
**💡 Typed Forms**
This feature addresses the number one issue on Angular’s GitHub repository. With typed forms, we benefit from stricter template type-checking. We are **informed at compile time**, whereas previously, issues would only **arise during runtime**.

And, just like any other typed variable, the code editor will provide autocompletion when you attempt to access a form property, great nah?
**💡 inject()**
One of the APIs I rely on daily in my applications.

There are numerous advantages to this API.
- For instance, I can set my observable at its declaration time (e.g., `teams: Observable<Team[]> = inject(TeamsService.getTeams();`), which wasn't possible previously because the declaration occurred before the constructor.
- In certain situations where you can’t use a constructor, a functional guard is a perfect example (a new feature that simplifies the usage of guards in Angular (available in v15)).
⚠️_inject() can only be called from an injection context, such as a constructor, a factory function, a field initializer, or a function used with_ `_runInInjectionContext_`_._
**💡All CommonModule pipes and directives were marked as standalone.**
This is another step toward unlocking the substantial potential of the standalone feature. Previously, when we wanted to use the date pipe, for instance, we had to import the `CommonModule`. This module not only contained the required pipe but also included other pipes, directives, …etc. These pipes/directives are now available as standalone entities, allowing you to import them individually according to your specific needs.

**💡 Setting inputs on** `**ComponentRef**` **the new** `**setInput()**` **method**
Great news for dynamic components: through the new `**setInput()**` method, you can intuitively and elegantly set component inputs.

**💡Add CanMatch guard to Route**
A new route guard allows the exclusion of a route from the matching process during navigation.

The `**CanLoad**` guard only specifies whether the code should be downloaded while `canActivate` determines whether the route should be activated. The`canMatch` is used for cases where you want to decide where to navigate based on some data. We can define multiple routes with the **same path** and activate or load the route based on specific conditions (who the user is for example).
**💡** `**NgOptimizedImage**` **directive (dev preview) (14.2)**
Great news for those who load many images in their apps, such as e-commerce applications. In terms of performance, this directive is the one to use in such cases, and it’s also available as a standalone directive!
With this directive, you can select the loading mode, either lazily or eagerly. You have the option to prioritize an image, and you can define parameters like width, height, fill, …etc.

Here is a [**great article**](https://developer.chrome.com/blog/angular-image-directive/) about all that you need to know about this directive!
**💡** `**createComponent**` **and** `**reflectComponentType**` **APIs (14.2)**
This is a replacement for the deprecated `**ComponentFactory**` API. Creating components dynamically is much easier.

**💡 New APIs to use Router without RouterModule (dev preview) (14.2)**
No need to use `RouterModule` to set up the Router anymore. Perfect toward a complete standalone component app, but it doesn’t require an app to use standalone APIs. Those APIs add more Router features in a tree-shakable way. You only import what you use!

## 📌At its 15
💡 Standalone APIs **(stable and production ready)** + schematics + HTTP/Router APIs.
In v15, it’s possible to create a complete standalone Angular app without NgModule.

**💡Improved stack traces in the browser console**
For DX, debugging improvements and tools are always welcomed 😆

**💡Hiding CLI config files by default**
Visually, it is stunning — cleaner with fewer elements for the eyes to read. However, this led to significant confusion, mainly when dealing with `environement` configuration files. Many projects depend on it.

**💡 Self-closing component tags (15.1)**
Add elegance 🎇 to Angular templates. Notice that for projected content, you still need to use a closing tag.

**💡 Add TestBed.runInInjectionContext to help test functions that use** `**inject**` **API (15.1)**
Let’s say you use a functional-based resolver guard that injects a service to get some data. To test the resolver function, we need to run the function in an injection context, which is not the case in unit tests (remember `**inject()**` can only be used in an injection context).
With the `**TestBed.inject(EnvironmentInjector).runInContext**` you’ll be able to run the function in an injection context like below:

**💡 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 provided with the `--guard-type`.
```
ng generate guard my-guard --functionalng generate guard my-guard --functional --guard-type canDeactivateng generate resolver resolve-data --functional
```
**💡 Generate functional interceptors too**
```
ng generate interceptor my-interceptor --functional
```
**💡 Generate environment or config files (15.1)**
The deleted env & config files by default starting from v15 was not a big success. The Angular team has provided us with schematics to generate them. So you’ll only have env/config files when you need them.
- Generates empty environment files for each project configuration
- Adds a `fileReplacement` option for each file
```
ng generate environments [--project name]ng generate config [karma|browserslist]
```
**💡 Support inline component Sass styles with esbuild builder (15.1)**
You can from v15.1 use Sass (scss or sass) syntax with inline component styles.

💡Add a `**withNavigationErrorHandler**` feature to `provideRouter` (15.2)
This feature replaces the `errorHandler` in `RouterModule.forRoot` option. Plus a bonus: it runs in an injection context, so `inject()` can be used to grab dependencies!

**💡 New schematic to convert to standalone (15.2)**
```
ng generate @angular/core:standalone
```
**💡 Directive Composition API**
A powerful API that gives you the power to pull in behaviors you need from other directive(s) (it can be from Angular CDK) and apply it to the host element of your component or directive.

## 📌At its 16
**💡EsBuild + Vite (dev preview)**
This is really a considerable change in Angular app building life. This new bundler is very fast and could reduce the build time considerably.
Experimental support for `ng build` using **_esbuild_** is already available. With v16 the tooling team has made some improvements to the Development Server (in dev preview). Now, you can run `ng serve` with **_esbuild_**.

**💡Signals (dev preview)**
The first step toward the new reactivity model and toward a zoneless app for Angular, which brings significant improvements to performance and developer experience.
- signal() — reactive values
- computed() — reactive value derived from other signals
- effect() — run code when reactive values change

Here is a quick get-started to learn Signals:
**💡 Hydration** [**(doc 📓)**](https://angular.io/guide/hydration)
Time for user experience improvements with non-destructive hydration support. Once the browser receives the rendered markup from the server and parses it as a DOM, Angular will traverse the structure, add event listeners, and create internal data structures. From that point, the application becomes interactive without requiring a rerendering process. This will fix the problem of encountering a “flicker” with Angular Universal.

**💡Required Inputs**
Inputs can be marked as required. So, at **compilation time**, required inputs will raise an error if they haven’t been set. This is great! You don’t need to check in `ngOnChange` whether the must-have inputs are set or not and throw errors by yourself! Intuitive and elegant! I give it a ❤️

**💡 Transform inputs**
For those who wish to transform the data easily passed into a component input.

**💡 Routing data as component inputs ❤️**
Another great feature! Now, mapping route data (params, query params, resolved data) directly to component inputs is possible ⚡️
_⚠️ Must be enabled in the_ `_provideRouter_`_._

Before and after!

By FAM
**💡**`**_takeUntilDestoryed_**` **&** `**DestoryRef**`
A flexible way to run instruction in `ngOnDestroy` without implementing the hook itself.
- Works in components, directives, pipes, and DI services.
- `**DestoryRef**` provides an alternative way of registering onDestroy lifecycle callbacks.

_⚠️_ `_takeUntilDestoryed_` needs to be called inside an injection context (like `inject()` ). Otherwise, you need to manually pass the `destoryRef`.

**💡Jest support (**_Experimental_**)**
Jest is so popular that the Angular team decided to integrate it. To try it out, you need to enable it in `angular.json` file.

**💡**`**mapToCanActivate**` **helper function**
It simplifies the migration to functional guards at the Route definition and provides more direct support for authoring class-based guards if desired.

**💡** `**ngComponentOutlet**` **has** `**inputs**` **now ❤️**
A new way to pass data to dynamically created components with the `**ngComponentOutlet**` directive! There is no need to use the injector to pass data unless you need to provide dependencies. In this case, you need to use the injector.

💡 `**provideServerRendering**` function to provide server capabilities to an application.

**💡** `**provideServiceWorker**` **function**
There is no need to have a NgModule to enable ServiceWorker in your app anymore. The API is similar to the existing `ServiceWorkerModule.register` method, which simplifies the migration.

**💡 standalone support to the Angular CLI schematics**
You can get started now right away with a completely standalone app.
```
ng new ng generate application
```
## 📌At its 17 (🔮 The coming soon future!)
This is a teaser 😁 for the upcoming v17, stay tuned a dedicated article will be released when v17 is out!
**💡 New built-in flow control**
I’ve previously talked about the forthcoming Angular built-in control flow and its RFC. Now, it’s becoming a reality. We’ll be able to experiment with it soon (and you can even take a shortcut by installing v17.0.0-next.8 😉). The RFC initially suggested the hash (#) syntax, but after receiving feedback from the community, the syntax has been modified. The same applies to the defer feature syntax as well.
Only when you try it, you’ll see its beauty and its power 💪 (see the before/after example below):
⚡️ `**trackBy**` becomes so simple, intuitive and elegant!
⚡️ Empty array use case managed for us behind the scenes thanks to the `**@empty**` block.
BTW, this is just a small example. Trust me!

**💡 Deferred loading** 🤯
Lazy loading within a template thanks to the `**@defer**` feature. This will definitely revolutionize the way we construct our templates in Angular. It offers more than just basic lazy loading. We can choose a condition(s) (on interaction (e.g. click)? on hover? when something happens (e.g. when hasFetchedData()),…etc.
The `**@defer**` can also be used with other blocs such as `**@error**`, `**@loading**` , …etc.

And much much much more!
> 💃 More details about the upcoming version new features will be covered in a dedicated article for the new release 🌟 Stay tuned!
That’s it for today, see ya 🙋