Skip to content

Commit a662114

Browse files
authored
docs(ngrx): add example of global state in component store (#18)
1 parent 8020159 commit a662114

File tree

1 file changed

+137
-0
lines changed

1 file changed

+137
-0
lines changed
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
---
2+
title: Global NgRx State and NgRx Component Store
3+
description: "Pull in global state and use in Component Store"
4+
tags: ["angular", "ngrx", "state"]
5+
pubDate: Feb 25, 2023
6+
contributedBy: "@JayCooperBell"
7+
---
8+
9+
An example of a simple global NgRx Store that is used in a ComponentStore that reacts to global state changes and manipulates
10+
the rest.
11+
12+
Set up a global NgRx Store with Effects.
13+
```typescript
14+
import { createAction, createFeature, createReducer, on } from '@ngrx/store';
15+
import { createEffect } from '@ngrx/effects';
16+
import { interval, map } from 'rxjs';
17+
18+
interface CounterState {
19+
counter: number;
20+
}
21+
22+
const initialCounterState: CounterState = {
23+
counter: 0,
24+
};
25+
26+
export const incrementCounter = createAction(
27+
'[Angular Snippets Example] Increment Counter'
28+
);
29+
30+
export const counterState = createFeature({
31+
name: 'counter',
32+
reducer: createReducer(
33+
initialCounterState,
34+
on(incrementCounter, (state) => ({
35+
...state,
36+
counter: state.counter + 1,
37+
}))
38+
),
39+
});
40+
41+
export const { selectCounter } = counterState;
42+
43+
export const incrementCounterEffect = createEffect(
44+
() => interval(1000).pipe(map(() => incrementCounter())),
45+
{ functional: true }
46+
);
47+
```
48+
49+
Add your global state to the application
50+
```typescript
51+
52+
53+
import { bootstrapApplication } from '@angular/platform-browser';
54+
import { AppComponent } from './app/app.component';
55+
import { provideState, provideStore } from '@ngrx/store';
56+
import {
57+
counterState,
58+
incrementCounterEffect,
59+
} from './app/global-state-in-component-store';
60+
import { provideEffects } from '@ngrx/effects';
61+
62+
bootstrapApplication(AppComponent, {
63+
providers: [
64+
provideStore({}),
65+
provideState(counterState),
66+
provideEffects({ incrementCounterEffect }),
67+
],
68+
}).catch((err) => console.error(err));
69+
```
70+
71+
Pull the global state into a component store
72+
```typescript
73+
import { Component, inject, Injectable } from '@angular/core';
74+
import { ComponentStore } from '@ngrx/component-store';
75+
import { Store } from '@ngrx/store';
76+
import { Observable, tap } from 'rxjs';
77+
import { AsyncPipe } from '@angular/common';
78+
79+
interface MyState {
80+
counter: number;
81+
}
82+
83+
@Injectable({ providedIn: 'root' })
84+
export class ComponentStoreWithGlobalState extends ComponentStore<MyState> {
85+
readonly counter$ = this.select((state) => state.counter);
86+
87+
private readonly store = inject(Store);
88+
89+
private readonly setCounter = this.updater((state, counter: number) => ({
90+
...state,
91+
counter,
92+
}));
93+
94+
private readonly multiplyGlobalStateByTwo = this.effect(
95+
(origin$: Observable<number>) =>
96+
origin$.pipe(tap((counter) => this.setCounter(counter * 2)))
97+
);
98+
99+
constructor() {
100+
super({ counter: 0 });
101+
102+
this.multiplyGlobalStateByTwo(this.store.select(selectCounter));
103+
}
104+
}
105+
106+
@Component({
107+
selector: 'component-store-with-global-state',
108+
standalone: true,
109+
providers: [ComponentStoreWithGlobalState],
110+
imports: [AsyncPipe],
111+
template: ` <div>{{ counter$ | async }}</div>`,
112+
})
113+
export class ComponentStoreWithGlobalStateComponent {
114+
readonly store = inject(ComponentStoreWithGlobalState);
115+
116+
readonly counter$ = this.store.counter$;
117+
}
118+
```
119+
120+
Use the component
121+
```typescript
122+
import { Component } from '@angular/core';
123+
import { ComponentStoreWithGlobalStateComponent } from './global-state-in-component-store';
124+
125+
@Component({
126+
standalone: true,
127+
selector: 'angular-snippet-examples-root',
128+
template: `
129+
<component-store-with-global-state></component-store-with-global-state>
130+
`,
131+
styles: [],
132+
imports: [
133+
ComponentStoreWithGlobalStateComponent,
134+
],
135+
})
136+
export class AppComponent {}
137+
```

0 commit comments

Comments
 (0)