-
Notifications
You must be signed in to change notification settings - Fork 41
feat: add mutation api #202
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
d845d42
to
383047d
Compare
experimental mutation API
383047d
to
b106303
Compare
Falls back to the current injector
…d out about exhaust semantics
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This review consists of two parts. Things that should be addressed before we merge it, and things that can be done later, as additional features.
I've added a TODO
prefix to all my comments that fall into the second category (which could be done later).
Here's a summary, where we could have separate Issues and PR contributions.
- #220
rxMutate
as fully standalone function which would also work outside the SignalStore - Documentation in Docusaurus
- Refactoring of Tests (depends on standalone
rxMutation
, we can do more directly in that file and don’t have to go through the complete SignalStore. - Allow
withMutations
to expose more tracking data of the mutation, likeisPending
,hasValue
. - E2E Tests for Mutation Demo
- Standalone and Promise-based
mutation
- #221 Standalone
httpMutation
in the same manner ashttpResource
. - Redesign of flatten operator: Should probably have a callback telling that a certain input has been skipped.
…essing to IsPending
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good to go. Well done Mr @manfredsteyer
This introduces `withMutations` as a new SignalStore feature, with initial support for RxJS-powered mutations via `rxMutation`. Example: ```typescript export const CounterStore = signalStore( withState({ counter: 0 }), withMutations((store) => ({ increment: rxMutation({ operation: (value: number) => { return httpClient.post('counter/increase', { value }); }, onSuccess: (result) => { patchState(store, { counter: result }); }, }), })), ); const counterStore = inject(CounterStore); counterStore.increment(1); console.log(counterStore.counter()); // prints 1 ```` --- - Mutations is the term the Angular team uses for a potential upcoming feature that complements *resources* (which are read-only). Mutations enable writing data back to the server. - To align with this mutation-based mindset, we are introducing custom mutation support in the toolkit. - The design is inspired by @markostanimirovic’s prototype: https://github.com/markostanimirovic/rx-resource-proto - Thanks to Marko for consulting with the NgRx team, and to Alex Rickabaugh (@alxhub) for the core mutation design. - We also took ideas from TanStack Query's mutation feature: https://tanstack.com/query/latest --- This commit lays the foundation for further expansion of mutation support in SignalStore.
rxMutation creates a mutation function in the store, delegating to a function/ method returning an observable, and takes care of race conditions by internally using mergeMap (default), switchMap, concatMap, or exhaustMap.
mutation also creates an async mutation function, delegating to a function/ method returning an observable. When the async function is awaited without throwing an exception, the caller can safely assume that it has been executed. However, here, the consumer is responsible for preventing race conditions.