Announcing NgRx v15: Standalone APIs, Type-safe projectors, Component and ComponentStore updates, and more!
Tags: ngrx, angular, webdev
Published: 2022-11-29 16:11:53


We are pleased to announce the latest major version of the NgRx framework with some exciting new features, bug fixes, and other updates.

---

## Standalone APIs for NgRx Libraries 🧙

Angular v14 introduced standalone features for components, pipes, and directives allow you to build Angular applications with NgModules primarily being optional. In Angular v15, the standalone APIs are no longer in developer preview.

To improve support for standalone features, all NgRx libraries that register functionality in Angular have an equivalent `provide*` API for compatibility with building Angular applications with standalone features. Let's take a look at the new APIs.

Root-level providers:

```ts
boostrapApplication(AppComponent, {
  providers: [
    provideStore(),
    provideEffects(AppEffects),
    provideStoreDevtools(),
    provideRouterStore(),
    provideEntityData(config, withEffects())
  ]  
});
```

In lazy-loaded features, such as route configs:

```ts
[
  {
    path: 'products',
    component: ProductsPageComponent,
    providers: [
      provideState(productsFeature),
      provideEffects(ProductsEffects)
    ]
  }
]
```

Thanks to [Jay Bell](https://twitter.com/JayCooperBell), [Santosh Yadav](https://twitter.com/SantoshYadavDev), and others for their help in contributing to these new APIs.

Check out [Tim's latest blog post](https://timdeschryver.dev/blog/you-should-take-advantage-of-the-improved-ngrx-apis) on how NgRx APIs has evolved over time and how you can take advantage of them.

---

## Announcing Enterprise Support 👨‍🏫

The NgRx collection of libraries will always remain open-source, MIT-licensed, and free to use. At the same time, we hear from companies that designing high-quality architecture could be challenging and additional help and guidance are needed.

Participating members of the NgRx team now offer *paid support* for those interest in NgRx workshops, training on best practices, architecture review, and more.

Visit our [Enterprise Support](https://ngrx.io/enterprise-support) page to learn more.

---

## NgRx Component marked as stable ✍

The NgRx Component package brings more reactivity to templates in Angular, along with providing support for fully zone-less Angular applications. NgRx Component provides two main features, the `ngrxPush` pipe and `ngrxLet` directive for more easily using observables in Angular component templates. 

In version 14, team member [Marko Stanimirović](https://twitter.com/MarkoStDev) completely rewrote the component package from the ground up to provide a more consistent way to handle observable and static data, improved performance for zone-less applications in Angular, and more. In version 15, the component package is no longer marked as **experimental** and is now marked as **stable** for developers to take advantage of with full support.

A new feature also added to `@ngrx/component` is the ability to pass a dictionary of observables in the template with the `ngrxLet` directive. A view model object is created from the observables provided.

```html
<ng-container *ngrxLet="{ users: users$, query: query$ } as vm">
  <app-search-bar [query]="vm.query"></app-search-bar>
  <app-user-list [users]="vm.users"></app-user-list>
</ng-container>
```

Read [this post](https://dev.to/ngrx/building-reactive-angular-templates-with-ngrx-component-4m1e) to learn more about NgRx Component.

---

## Strict Type-safety For the Selector Projector 🔒

When testing selectors built with NgRx Store, the projector function is a way to provide inputs to a selector and assert against the result. Previously the projector function allowed the arguments passed to it to be less strict, and was not inferred from the selector itself. With version 15, the projector function is now strictly typed out of the box, allowing for more type safety about the inputs passed into the selector.

The projector is strict by default, but can be bypassed with an any type assertion to specify a less specific type.

```ts
const mySelector = createSelector(
  () => 'one',
  () => 2,
  (one, two) => 3
);

// Type is projector(s1: string, s2: number): number
mySelector.projector(); // <-- Results in type error.
```

To opt-out of the new behavior, cast the projector function itself.

```ts
const mySelector = createSelector(
  () => 'one',
  () => 2,
  (one, two) => 3
)

(mySelector.projector as any)();
```

Thanks to [David Shortman](https://github.com/david-shortman) for contributing to this feature.

## Simplified View Models with ComponentStore ✨

Creating view models is a recommended way to consolidate multiple streams in a clean API to provide to your components. ComponentStore allows you to easily compose these streams from multiple sources. To further improve this, we've added a new signature to the `ComponentStore.select` method that allows you to provide a dictionary of observables, and an observable dictionary of those values is returned.

Before the new method, the ComponentStore projector was a repeat of its inputs.

```ts
readonly vm$: Observable<SomeViewModel> = this.select(
  this.selectedTab$,
  this.routerStateService.baseListRoute$,
  this.secondaryNavigationItems$,
  this.isFlaggedPage$,
  this.pageTitle$,
  this.hasError$,
  this.errorMessage$,
  (
    selectedTab,
    baseRoute,
    secondaryNavTabs,
    isFlaggedPage,
    pageTitle,
    hasError,
    errorMessage,
  ) => ({
    selectedTab,
    baseRoute,
    secondaryNavTabs,
    isFlaggedPage,
    pageTitle,
    hasError,
    errorMessage,
  }),
  { debounce: true },
); 
```

- The new select signature makes this much more concise.

```ts
readonly vm$: Observable<SomeViewModel> = this.select({
  selectedTab: this.selectedTab$,
  baseRoute: this.routerStateService.baseListRoute$,
  secondaryNavTabs: this.secondaryNavigationItems$,
  isFlaggedPge: this.isFlaggedPage$,
  pageTitle: this.pageTitle$,
  hasError: this.hasError$,
  errorMessage: this.errorMessage$,
}, { debounce: true }); 
```

We also plan to add support for providing a dictionary to selectors in NgRx Store.

---

Swag store and Discord Server! 👕

You can get official NgRx swag through our [store](https://ngrx.threadless.com)! T-shirts with the NgRx logo are available in many different sizes, materials, and colors. We will look at adding new items to the store such as stickers, magnets, and more in the future. Visit our store to get your NgRx swag today!

Join our [discord server](https://discord.gg/ngrx) for those who want to engage with other members of the NgRx community, old and new. 

---

## Deprecations and Breaking Changes 💥

This release contains bug fixes, deprecations, and breaking changes. For most of these deprecations or breaking changes, we've provided a migration that automatically runs when you upgrade your application to the latest version.

Take a look at the [version 15 migration guide](https://ngrx.io/guide/migration/v15) for complete information regarding migrating to the latest release. The complete [CHANGELOG](https://github.com/ngrx/platform/blob/master/CHANGELOG.md) can be found in our GitHub repository.

---

## Upgrading to NgRx 15 🗓️

To start using NgRx 15, make sure to have the following minimum versions installed:

- Angular version 15.x
- Angular CLI version 15.x
- TypeScript version 4.8.x
- RxJS version ^6.5.x or RxJS version ^7.5.x

NgRx supports using the Angular CLI ng update command to update your NgRx packages. To update your packages to the latest version, run the command:

```sh
ng update @ngrx/store
```

---

## Contributing to NgRx 🥰

We're always trying to improve the docs and keep them up-to-date for users of the NgRx framework. To help us, you can start contributing to NgRx. If you're unsure where to start, come take a look at our contribution guide and watch the introduction video Jan-Niklas Wortmann and Brandon Roberts have made to help you get started.

Thanks to all our contributors and sponsors

NgRx continues to be a community-driven project. Design, development, documentation, and testing all are done with the help of the community. We've recently added a community section to the NgRx team page that lists every person that has contributed to the platform.

If you are interested in contributing, visit our GitHub page and look through our open issues, some marked specifically for new contributors. We also have active GitHub discussions for new features and enhancements.

---

## Sponsor NgRx 💲

We are looking for our next **Gold** sponsor, so if your company wants to sponsor the continued development of NgRx, please visit our [GitHub Sponsors](https://github.com/sponsors/ngrx) page for different sponsorship options, or contact us directly to discuss other sponsorship opportunities.

We want to give a big thanks to our Silver sponsor, Narhwal Technologies! Nrwl has been a longtime promoter of NgRx as a tool for building large Angular applications, and is committed to supporting open source projects that they rely on for Nx.

Follow us on [Twitter](https://twitter.com/ngrx_io) for the latest updates about the NgRx platform.