RFC(`@ngrx/signals`): Add `withProps` feature
Which @ngrx/* package(s) are relevant/related to the feature request?
signals
Information
This feature request suggests adding another SignalStore base feature - withProps. It would allow static properties or observables to be defined as SignalStore members.
export const BooksStore = signalStore(
withEntities<Book>(),
withRequestStatus(),
withProps(({ isFulfilled }) => ({
fulfilled$: toObservable(isFulfilled).pipe(filter(Boolean)),
})),
);
It can also be used for defining all dependencies in a single place:
export const MyStore = signalStore(
withProps(() => ({
service1: inject(Service1),
service2: inject(Service2),
})),
withMethods(({ service1, service2 }) => ({
method1() {
service1.foo();
},
method2() {
service2.bar();
},
}))
);
The withProps feature will be useful for library authors to reuse the same config across multiple features:
const SOURCE = Symbol('SOURCE');
function withSource(source: string) {
return signalStoreFeature(withProps({ [SOURCE]: source }));
}
export const BooksStore = signalStore(
withSource('BooksStore'),
withDevtools(),
withEvents({
loadedSuccess: props<{ books: Book[] }>(),
loadedFailure: props<{ error: string }>(),
})
);
In this example, both withDevtools and withEvents would use the source from the withSource feature.
Signatures
The withProps feature would have 2 signatures:
withProps({ foo: 'bar' })withProps(() => ({ foo: 'bar' }))
- The
withPropsfactory function would accept previously defined state signals, computed signals, and properties. withComputed,withMethods, andwithHookswould accept previously defined properties.
I would be willing to submit a PR to fix this issue
- [X] Yes
- [ ] No
Yes, that would be an addition, we definitely should have. Just two questions:
- Do we now have constraints for the property type, or can it be anything?
- You stated that the factory function gets the existing slices and computeds. I guess it would also get the previous props? Why do we not pass the methods as well?
As suggested something like this last week on discord when talking with @rainerhahnekamp. It would be super useful to open many new capabilities and to avoid hacks with Proxy applied on method in withMethods.
Are there any more details about limitations and where those props would be exposed? I'm hopping to have access to them in withComputed.
I updated the RFC description with more details:
- The
withPropsfactory function would accept previously defined state signals, computed signals, and properties. withComputed,withMethods, andwithHookswould accept previously defined properties.
This would be useful!
Can props be private the same way state/computed/methods are?
IMO it makes a lot of sense when integrating with libs/things from outside of angular ecosystem, which don't fit any of existing withState, withComputed etc.
The only thing which bothers me is the name - withProps. The "property" word doesn't outline what is the key here - being static. How about withStatic?
@ducin thats why I also proposed alternative name withExplicit
Edited: Ahhh it was in other discussion
Hi guys, I have a legit use case for signals
Let's pretend I have one app state x (contained in a store, with its own computed and methods) But I also have n lazy features that might depend up to a certain point on this app state, but given they are lazy, I might never load them, so I don't include them eagerly in the main state.
However, if I load them, I need to take care of types and members being exposed upstream (app state). The idea is that I can build a core state, and create as many "modules" as my logic needs, and plug them lazily.
When I load the lazy feature n1, I'd like to have access to the same instance of the app state, react to changes in the state and "extend" with new computed and methods.
I was exploring signalStoreFeature, but these are intended to extend instances of a store ahead of time. This issue looks interesting, and it might be the solution I'm looking for.
Could you please confirm if this feature will satisfy the use case I mentioned? otherwise, I will need to look for alternatives. Thanks in advance