RFC - Signals in NGXS #1977
Replies: 12 comments 3 replies
-
Hi, |
Beta Was this translation helpful? Give feedback.
-
In my opinion, it should be the best to keep same names for both APIs. This will be intuitive and won't lead to any confusion if both are used across the app. Thus I'd be against having signal-based The cleanest solution is to add Going with option 2.3 by deprecating
|
Beta Was this translation helpful? Give feedback.
-
Thanks for the great proposal Mark. In my opinion, it is best to introduce signals explicitly like shown on the solution 2.2 In a future release we can, maybe with the help of a migration script, do a API change to make it cleaner. |
Beta Was this translation helpful? Give feedback.
-
Great to see signals coming to NGXS! 1) Property Initializer APII really like Option A, F and G. I think signals are the right way to go in the future and there's no current I'm not yet sure which of those three options I prefer for observables though. I know and understand the Another proposal: ComposablesI've only recently come across the pattern of composables, used e.g. in Vue. They're a design-pattern that lets us add ("compose") functionality to e.g. components with simple function calls. They have a common naming pattern: the function-name is prefixed with Similarly, instead of a 2) Store instance APIOption 2 seems like the obvious option right now, but in the long run, I think this Have you considered something like 1) F here? So adding a second argument, where we have to explicitly specify that we want an observable: store.select(MySelector); // returns a signal
store.select(MySelector, { observable: true }); // returns an observable After all, it would be best to keep both API's similar. Further thoughtsAre there any plans to add signal support to other parts of NGXS yet? Like dispatching actions, receiving a stream of actions, or even deeper support for signals in selectors |
Beta Was this translation helpful? Give feedback.
-
@markwhitfeld For me option E seems interesting. Can you explain your concerns regarding that one a little bit? Is there a possibility that we could use single property (created from select(MySelector)) to play with it as observable and as signal based on our needs? |
Beta Was this translation helpful? Give feedback.
-
My vote is for option E (🎯). It looks clean! Ofcourse it would be nice to know the conceptual reservations there. |
Beta Was this translation helpful? Give feedback.
-
I think option |
Beta Was this translation helpful? Give feedback.
-
I like option @markwhitfeld, where are you expecting this to be released? |
Beta Was this translation helpful? Give feedback.
-
Hi there! I'm curious if there are any recent updates or specific plans for the future? It would be great to get some insights into what's coming next. Thanks! |
Beta Was this translation helpful? Give feedback.
-
After much discussion, we have found that there were some topics that were difficult to come to a consensus on and therefore we will take a smaller incremental approach that adds the definites that were easy to agree on. These are is the initial proposed API additions for signals:
PS. The topics that are difficult to come to a consensus on, due to the vast array of Angular user views that may exist:
|
Beta Was this translation helpful? Give feedback.
-
What about having different import paths. It seems like we want to guide devs to use the signal first approach. In that case we could have an import that uses the legacy Store / select (observable first). In that case, the breaking change that would be introduced would simply be to change the import paths (a "find all and replace"). import { Store, select } from '@ngxs/store'; // signal first
import { Store as ObservableStore, select as selectObservable } from '@ngxs/store/observable'; // observable first |
Beta Was this translation helpful? Give feedback.
-
F or G. But I think F is good for me. |
Beta Was this translation helpful? Give feedback.
-
A few ideas are being bounced around on what this could look like.
We are seeking proposals of ideas from the community.
Please create an 'Answer' to this discussion with your proposal which can then be discussed in the thread for it.
Please ensure that it clearly states the following aspects of your proposal:
Please also take the time to look at other proposals and engage in respectful discussion.
We will consider every proposal. Please do not be offended if yours is not accepted.
We want to keep the core of NGXS as simple and maintainable as possible, and sometimes bigger ideas are better as plugins.
I would like to mention that observables and signals are not mutually exclusive.
They each have their strengths and weaknesses.
Some points on Signals
Some points on Observables:
async
pipe is often used to make this simplerPart of the intention with this RFC is to define what these APIs look like, and how they can seamlessly co-exist and intuitively lead the developer to success for each use case.
Initial Proposal
Over the past few months, we have been working closely with the Angular team, giving feedback and driving the Signals API to be a useful, and well-thought-out addition to Angular. This has been part of an internal working group with other open-source authors (NgRx, RXAngularm and others) and we have had great discussions as part of this process.
So now, to add my thoughts on what the API for signals could look like...
There are a few prospective API surfaces to cover.
signal
,computed
, etc. APIs exposed in Angular)Store
(eg.store.select(...)
)@Select
decorator).@Select
decorators.As mentioned above the 3rd API will be deprecated and will not form part of this discussion, so let's look at the first 2.
1) Property Initializer API
The ideal API signature here would be:
And the usage in a component would look like the following:
In my mind, this would be the ideal, but there are some points for consideration:
select(...)
would return a Signal, butstore.select(...)
would return an observable.If we provide this sort of property initializer for Signals, then should we also create one for Observables?
@Select
decorator.DestroyRef
from Angular 16 to automatically unsubscribe when the service or component is destroyed.select$(...)
, where the$
on the end mirrors the convention of observable properties. For example:Alternatives
Let's look at this API vs some alternative namings. It would be great if any commenters on this mentioned their thoughts on these:
select(MySelector)
select$(MySelector)
selectSignal(MySelector)
select(MySelector)
store
. Possibly an "Observables-first" approach in the view, which could lead developers in the wrong directiontoSignal(MySelector)
toObservable(MySelector)
@angular/core/rxjs-interop
select(MySelector)
this.store.select(MySelector)
select(MySelector)
select(MySelector)
NgxsSignal
that supports both the Signal and Observable APIs. Some conceptual reservations here, but if there is interest in what this would look like, then I can add another proposal comment to the RFC.select(MySelector)
select(MySelector, { observable: true })
select(MySelector)
selectObservable(MySelector)
selectSignal(MySelector)
select$(MySelector)
selectSignal(MySelector)
selectObservable(MySelector)
2) Store instance API
Depending on the property initializer chosen above, we would need to decide how the
store
instance API needs to grow or evolve.Currently
store.select(MySelector)
returns an Observable.There are a few options with what we do:
store.selectSignal(MySelector)
store.select
to be the Signal based API by some point in the future.store.select
in the interim and create a new Observable based function likestore.select$(MySelector)
. Then at some point in the future, we reintroduce thestore.select(MySelector)
function as a signal based API.My preference is option 2.2 here.
Beta Was this translation helpful? Give feedback.
All reactions