https://github.com/ngworker/router-component-store
A strictly typed lightweight alternative to NgRx Router Store and ActivatedRoute.
https://github.com/ngworker/router-component-store
angular component-store ngrx router state-management
Last synced: 2 months ago
JSON representation
A strictly typed lightweight alternative to NgRx Router Store and ActivatedRoute.
- Host: GitHub
- URL: https://github.com/ngworker/router-component-store
- Owner: ngworker
- License: mit
- Created: 2021-11-13T22:18:50.000Z (over 3 years ago)
- Default Branch: main
- Last Pushed: 2025-02-12T20:48:12.000Z (4 months ago)
- Last Synced: 2025-04-09T23:15:42.079Z (2 months ago)
- Topics: angular, component-store, ngrx, router, state-management
- Language: TypeScript
- Homepage:
- Size: 1.93 MB
- Stars: 37
- Watchers: 1
- Forks: 2
- Open Issues: 5
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Funding: .github/FUNDING.yml
- License: LICENSE
Awesome Lists containing this project
README
# Router Component Store
[`@ngworker/router-component-store`](https://www.npmjs.com/package/@ngworker/router-component-store)
A strictly typed lightweight alternative to NgRx Router Store (`@ngrx/router-store`) and `ActivatedRoute`.
## Compatibility
Required peer dependencies:
- Angular >=15.0
- NgRx Component Store >=15.0
- RxJS >=7.5
- TypeScript >=4.8Published with partial Ivy compilation.
Find additional documentation in the [github.com/ngworker/router-component-store/docs](https://github.com/ngworker/router-component-store/tree/main/docs) directory.
## Guiding principles
Router Component Store is meant as a lightweight alternative to NgRx Router Store that additionaly can be used as a replacement for `ActivatedRoute` at any route level.
The following principles guide the development of Router Component Store.
- The global router store closely matches NgRx Router Store selectors
- Local router stores closely match `ActivatedRoute` observable properties
- Router state is immutable and serializable
- The API is strictly and strongly typed## API
### RouterStore
A `RouterStore` service has the following public properties.
| API | Description |
| --------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| `currentRoute$: Observable` | Select the current route. |
| `fragment$: Observable` | Select the current route fragment. |
| `queryParams$: Observable` | Select the current route query parameters. |
| `routeData$: Observable` | Select the current route data. |
| `routeParams$: Observable` | Select the current route parameters. |
| `title$: Observable` | Select the resolved route title. |
| `url$: Observable` | Select the current URL. |
| `selectQueryParam(param: string): Observable` | Select the specified query parameter. |
| `selectRouteData(key: string): Observable` | Select the specified route data. |
| `selectRouteParam(param: string): Observable` | Select the specified route parameter. |
| `selectRouterEvents(...acceptedRouterEvents: RouterEvent[]): Observable` | Select router events of the specified router event types. |A `RouterStore` service is provided by using either `provideGlobalRouterStore`or `provideLocalRouterStore`.
The _global_ `RouterStore` service is provided in a root environment injector and is never destroyed but can be injected in any injection context.
It emits values similar to `@ngrx/router-store` selectors. A comparison is in the documentation.
A _local_ `RouterStore` requires a component-level provider, follows the lifecycle of that component, and can be injected in declarables as well as other component-level services.
It emits values similar to `ActivatedRoute`. A comparison is in the documentation.
#### Global router store
An application-wide router store that can be injected in any injection context. Use `provideGlobalRouterStore` to provide it in a root environment injector.
Use a global router store instead of NgRx Router Store.
Providing in a standalone Angular application:
```typescript
// main.ts
// (...)
import { provideGlobalRouterStore } from '@ngworker/router-component-store';bootstrapApplication(AppComponent, {
providers: [provideGlobalRouterStore()],
}).catch((error) => console.error(error));
```Providing in a classic Angular application:
```typescript
// app.module.ts
// (...)
import { provideGlobalRouterStore } from '@ngworker/router-component-store';@NgModule({
// (...)
providers: [provideGlobalRouterStore()],
})
export class AppModule {}
```Usage in service:
```typescript
// hero.service.ts
// (...)
import { RouterStore } from '@ngworker/router-component-store';@Injectable({
providedIn: 'root',
})
export class HeroService {
#routerStore = inject(RouterStore);activeHeroId$: Observable =
this.#routerStore.selectRouteParam('id');
}
```Usage in component:
```typescript
// hero-detail.component.ts
// (...)
import { RouterStore } from '@ngworker/router-component-store';@Component({
// (...)
})
export class HeroDetailComponent {
#routerStore = inject(RouterStore);heroId$: Observable =
this.#routerStore.selectRouteParam('id');
}
```#### Local router store
A component-level router store. Can be injected in any directive, component,
pipe, or component-level service. Explicitly provided in a component sub-tree
using `Component.providers` or `Component.viewProviders`.Use a local router store instead of `ActivatedRoute`.
Usage in component:
```typescript
// hero-detail.component.ts
// (...)
import {
provideLocalRouterStore,
RouterStore,
} from '@ngworker/router-component-store';@Component({
// (...)
providers: [provideLocalRouterStore()],
})
export class HeroDetailComponent {
#routerStore = inject(RouterStore);heroId$: Observable =
this.#routerStore.selectRouteParam('id');
}
```### Serializable router state
Several of the Angular Router's types are recursive which means that they aren't serializable. The router stores exclusively use serializable types to support advanced state synchronization strategies.
#### MinimalActivatedRouteSnapshot
The `MinimalActivatedRouteSnapshot` interface is used for the observable `RouterStore#currentRoute$` property. This interface is a serializable subset of the Angular Router's `ActivatedRouteSnapshot` class and has the following public properties.
| API | Description |
| --------------------------------------------------- | ------------------------------------------------ |
| `children: MinimalActivatedRouteSnapshot[]` | The children of this route in the route tree. |
| `data: StrictRouteData` | The static and resolved data of this route. |
| `firstChild: MinimalActivatedRouteSnapshot \| null` | The first child of this route in the route tree. |
| `fragment: string \| null` | The URL fragment shared by all routes. |
| `outlet: string` | The outlet name of the route. |
| `params: StrictRouteParams` | The matrix parameters scoped to this route. |
| `queryParams: StrictQueryParams` | The query parameters shared by all routes. |
| `routeConfig: Route \| null` | The configuration used to match this route. |
| `title: string \| undefined` | The resolved route title. |
| `url: UrlSegment[]` | The URL segments matched by this route. |#### StrictQueryParams
The `StrictQueryParams` type is used for query parameters in the `MinimalActivatedRouteSnapshot#queryParams` and `RouterStore#queryParams$` properties. It is a strictly typed version of the Angular Router's `Params` type where members are read-only and the `any` member type is replaced with `string | readonly string[] | undefined`.
`StrictQueryParams` has the following signature.
```typescript
export type StrictQueryParams = {
readonly [key: string]: string | readonly string[] | undefined;
};
```#### StrictRouteData
The `StrictRouteData` interface is used for the `MinimalActivatedRouteSnapshot#data` and `RouterStore#routeData$` properties. This interface is a serializable subset of the Angular Router's `Data` type. In particular, the `symbol` index in the Angular Router's `Data` type is removed. Additionally, the `any` member type is replaced with `unknown` for stricter typing.
`StrictRouteData` has the following signature.
```typescript
export type StrictRouteData = {
readonly [key: string]: unknown;
};
```#### StrictRouteParams
The `StrictRouteParams` type is used for route parameters in the `MinimalActivatedRouteSnapshot#params` and `RouterStore#routeParams$` properties. It is a strictly typed version of the Angular Router's `Params` type where members are read-only and the `any` member type is replaced with `string | undefined`.
`StrictRouteParams` has the following signature.
```typescript
export type StrictRouteParams = {
readonly [key: string]: string | undefined;
};
```