You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
NgRx Toolkit is an extension to the NgRx Signals Store. **It is still in beta** but already offers following features:
9
+
NgRx Toolkit is an extension to the NgRx Signals Store. **It is still in beta** but already offers features, like:
10
10
11
11
- Devtools: Integration into Redux Devtools
12
12
- Redux: Possibility to use the Redux Pattern (Reducer, Actions, Effects)
13
+
- Storage Sync: Synchronize the Store with Web Storage
13
14
- Redux Connector: Map NgRx Store Actions to a present Signal Store
14
15
15
16
To install it, run
@@ -18,18 +19,36 @@ To install it, run
18
19
npm i @angular-architects/ngrx-toolkit
19
20
```
20
21
22
+
Starting with 18.0.0-rc.2, we have a [strict version dependency](#why-is-the-version-range-to-the-ngrxsignals-dependency-so-strict) to `@ngrx/signals`:
-[Redux Connector for the NgRx Signal Store `createReduxState()`](#redux-connector-for-the-ngrx-signal-store-createreduxstate)
28
43
-[Use a present Signal Store](#use-a-present-signal-store)
29
44
-[Use well-known NgRx Store Actions](#use-well-known-ngrx-store-actions)
30
45
-[Map Actions to Methods](#map-actions-to-methods)
31
46
-[Register an Angular Dependency Injection Provider](#register-an-angular-dependency-injection-provider)
32
47
-[Use the Store in your Component](#use-the-store-in-your-component)
48
+
-[FAQ](#faq)
49
+
-[Why is the version range to the `@ngrx/signals` dependency so strict?](#why-is-the-version-range-to-the-ngrxsignals-dependency-so-strict)
50
+
-[I have an idea for a new extension, can I contribute?](#i-have-an-idea-for-a-new-extension-can-i-contribute)
51
+
-[I require a feature that is not available in a lower version. What should I do?](#i-require-a-feature-that-is-not-available-in-a-lower-version-what-should-i-do)
33
52
34
53
35
54
## Devtools: `withDevtools()`
@@ -40,7 +59,7 @@ This extension is very easy to use. Just add it to a `signalStore`. Example:
The features ``withCallState`` and ``withUndoRedo`` are optional, but when present, they enrich each other.
129
+
The features `withCallState` and `withUndoRedo` are optional, but when present, they enrich each other.
114
130
115
-
The Data Service needs to implement the ``DataService`` interface:
131
+
The Data Service needs to implement the `DataService` interface:
116
132
117
-
```typescript
133
+
```typescript
118
134
@Injectable({
119
135
providedIn: 'root'
120
136
})
@@ -172,30 +188,30 @@ export class FlightSearchSimpleComponent {
172
188
173
189
## DataService with Dynamic Properties
174
190
175
-
To avoid naming conflicts, the properties set up by ``withDataService`` and the connected features can be configured in a typesafe way:
191
+
To avoid naming conflicts, the properties set up by `withDataService` and the connected features can be configured in a typesafe way:
176
192
177
193
```typescript
178
194
exportconst FlightBookingStore =signalStore(
179
195
{ providedIn: 'root' },
180
196
withCallState({
181
-
collection: 'flight'
197
+
collection: 'flight',
182
198
}),
183
-
withEntities({
184
-
entity: type<Flight>(),
185
-
collection: 'flight'
199
+
withEntities({
200
+
entity: type<Flight>(),
201
+
collection: 'flight',
186
202
}),
187
203
withDataService({
188
-
dataServiceType: FlightService,
204
+
dataServiceType: FlightService,
189
205
filter: { from: 'Graz', to: 'Hamburg' },
190
-
collection: 'flight'
206
+
collection: 'flight',
191
207
}),
192
208
withUndoRedo({
193
209
collections: ['flight'],
194
-
}),
210
+
})
195
211
);
196
212
```
197
213
198
-
This setup makes them use ``flight`` as part of the used property names. As these implementations respect the Type Script type system, the compiler will make sure these properties are used in a typesafe way:
214
+
This setup makes them use `flight` as part of the used property names. As these implementations respect the Type Script type system, the compiler will make sure these properties are used in a typesafe way:
199
215
200
216
```typescript
201
217
@Component(...)
@@ -236,6 +252,47 @@ export class FlightSearchDynamicComponent {
236
252
}
237
253
```
238
254
255
+
## Storage Sync `withStorageSync()`
256
+
257
+
`withStorageSync` adds automatic or manual synchronization with Web Storage (`localstorage`/`sessionstorage`).
258
+
259
+
> [!WARNING]
260
+
> As Web Storage only works in browser environments it will fallback to a stub implementation on server environments.
261
+
262
+
Example:
263
+
264
+
```ts
265
+
const SyncStore =signalStore(
266
+
withStorageSync<User>({
267
+
key: 'synced', // key used when writing to/reading from storage
268
+
autoSync: false, // read from storage on init and write on state changes - `true` by default
269
+
select: (state:User) =>Partial<User>, // projection to keep specific slices in sync
270
+
parse: (stateString:string) =>State, // custom parsing from storage - `JSON.parse` by default
271
+
stringify: (state:User) =>string, // custom stringification - `JSON.stringify` by default
272
+
storage: () =>sessionstorage, // factory to select storage to sync with
273
+
})
274
+
);
275
+
```
276
+
277
+
```ts
278
+
@Component(...)
279
+
publicclassSyncedStoreComponent {
280
+
private syncStore =inject(SyncStore);
281
+
282
+
updateFromStorage():void {
283
+
this.syncStore.readFromStorage(); // reads the stored item from storage and patches the state
284
+
}
285
+
286
+
updateStorage():void {
287
+
this.syncStore.writeToStorage(); // writes the current state to storage
288
+
}
289
+
290
+
clearStorage():void {
291
+
this.syncStore.clearStorage(); // clears the stored item in storage
292
+
}
293
+
}
294
+
```
295
+
239
296
## Redux Connector for the NgRx Signal Store `createReduxState()`
240
297
241
298
The Redux Connector turns any `signalStore()` into a Gobal State Management Slice following the Redux pattern.
@@ -367,3 +424,24 @@ export class FlightSearchReducConnectorComponent {
367
424
}
368
425
}
369
426
```
427
+
## FAQ
428
+
429
+
### Why is the version range to the `@ngrx/signals` dependency so strict?
430
+
431
+
The strict version range for @ngrx/signals is necessary because some of our features rely on encapsulated types, which can change even in a patch release.
432
+
433
+
To ensure stability, we clone these internal types and run integration tests for each release. This rigorous testing means we may need to update our version, even for a patch release, to maintain compatibility and stability.
434
+
435
+
### I have an idea for a new extension, can I contribute?
436
+
437
+
Yes, please! We are always looking for new ideas and contributions.
438
+
439
+
Since we don't want to bloat the library, we are very selective about new features. You also have to provide the following:
440
+
- Good test coverage so that we can update it properly and don't have to call you 😉.
441
+
- A use case showing the feature in action in the demo app of the repository.
442
+
- An entry to the README.md.
443
+
444
+
### I require a feature that is not available in a lower version. What should I do?
445
+
446
+
Please create an issue. Very likely, we are able to cherry-pick the feature into the lower version.
NgRx Toolkit is an extension to the NgRx Signals Store. **It is still in beta** but already offers following features:
9
+
NgRx Toolkit is an extension to the NgRx Signals Store. **It is still in beta** but already offers features, like:
10
10
11
11
- Devtools: Integration into Redux Devtools
12
12
- Redux: Possibility to use the Redux Pattern (Reducer, Actions, Effects)
13
+
- Storage Sync: Synchronize the Store with Web Storage
13
14
- Redux Connector: Map NgRx Store Actions to a present Signal Store
14
15
15
16
To install it, run
@@ -18,18 +19,36 @@ To install it, run
18
19
npm i @angular-architects/ngrx-toolkit
19
20
```
20
21
22
+
Starting with 18.0.0-rc.2, we have a [strict version dependency](#why-is-the-version-range-to-the-ngrxsignals-dependency-so-strict) to `@ngrx/signals`:
-[Redux Connector for the NgRx Signal Store `createReduxState()`](#redux-connector-for-the-ngrx-signal-store-createreduxstate)
28
43
-[Use a present Signal Store](#use-a-present-signal-store)
29
44
-[Use well-known NgRx Store Actions](#use-well-known-ngrx-store-actions)
30
45
-[Map Actions to Methods](#map-actions-to-methods)
31
46
-[Register an Angular Dependency Injection Provider](#register-an-angular-dependency-injection-provider)
32
47
-[Use the Store in your Component](#use-the-store-in-your-component)
48
+
-[FAQ](#faq)
49
+
-[Why is the version range to the `@ngrx/signals` dependency so strict?](#why-is-the-version-range-to-the-ngrxsignals-dependency-so-strict)
50
+
-[I have an idea for a new extension, can I contribute?](#i-have-an-idea-for-a-new-extension-can-i-contribute)
51
+
-[I require a feature that is not available in a lower version. What should I do?](#i-require-a-feature-that-is-not-available-in-a-lower-version-what-should-i-do)
33
52
34
53
35
54
## Devtools: `withDevtools()`
@@ -405,3 +424,24 @@ export class FlightSearchReducConnectorComponent {
405
424
}
406
425
}
407
426
```
427
+
## FAQ
428
+
429
+
### Why is the version range to the `@ngrx/signals` dependency so strict?
430
+
431
+
The strict version range for @ngrx/signals is necessary because some of our features rely on encapsulated types, which can change even in a patch release.
432
+
433
+
To ensure stability, we clone these internal types and run integration tests for each release. This rigorous testing means we may need to update our version, even for a patch release, to maintain compatibility and stability.
434
+
435
+
### I have an idea for a new extension, can I contribute?
436
+
437
+
Yes, please! We are always looking for new ideas and contributions.
438
+
439
+
Since we don't want to bloat the library, we are very selective about new features. You also have to provide the following:
440
+
- Good test coverage so that we can update it properly and don't have to call you 😉.
441
+
- A use case showing the feature in action in the demo app of the repository.
442
+
- An entry to the README.md.
443
+
444
+
### I require a feature that is not available in a lower version. What should I do?
445
+
446
+
Please create an issue. Very likely, we are able to cherry-pick the feature into the lower version.
0 commit comments