It's very interesting to see how your approach evolves from a video to another. It teaches us how you analyse a given problem and find a suitable solution, while keeping in mind what could be improved. Thank you for your dedication 👍
Forms are still a headache for me to this day. I'm glad to know that signals could potentially help alleviate some of the annoyance... Though I'm starting more and more to look towards template-driven forms, which seem to scale better than what people tend to say, I feel
Great video Josh! You would love the work Tim Deschryver has done with ng-signal-forms! It's built entirely on signals and ngModel, which means you get all what's beautiful this added layer on top of reactive form, without having to deal with reactive forms :D Validators that are disabled/enabled based on form state, multi page forms driven by a single signal form, debounced inputs, async validation, etc. Would love for you to give it a try and to hear your thoughts on it!
I like the approach here. I also feel like there's work to be done to reach a state of things that would be beginner friendly, or if not beginner, not a huge expert. I see the current state of Angular like a transition, and I enjoy these experiments. Thanks Josh
Agreed and as I mentioned in another comment I don't really see this particular approach as a solution to forms generally, I think a more targeted/specific solution will be better. But for people who are using signalSlice or some approach that works similarly, this could be a nice way to integrate into existing patterns (and then maybe when better patterns come along, state management approaches like signalSlice might just integrate into those instead)
Instead of adding/removing validators on a control I would write one that take that other control as an input and react to changes on that (haven't tried this particular case). Or one could add a custom validator to the FormGroup. Then you can remove some imperative piece. Thanks for your videos!
Hey Josh, Question: It appears signal slice is used here as a way to manage state for a view-model. It is directly tied to a form. The values of the form are stored in the state object. How would you go about "pushing" these values to store that tracks state on the level of a feature (or even global state). Probably it is better to define the form slice as a source for the feature-store slice. How would you expose changes on the form slice as a source? Would you use toObservable for this?
Yes, this is what I have been doing to pull in state from one slice as a source for another. e.g: const audioUploaded$ = toObservable(wordsService.words).pipe( filter(Boolean), map(() => ({ status: 'uploaded' as const })) ); In this example "wordsService" is the signalSlice
@@JoshuaMorony Cool, tnx for the confirmation and the quick response. Follow up question: How do you deal with the fact that in the case of this video, the form-slice lives in a view component and is bound to Formbuilder (which is clearly view oriented) and that this form slice should be able to act as a source for a different slice that is a feature slice. This means the feature slice (which would typically live in a service-like structure or a store) needs to depend on a slice that lives in the view, to be able to define it as a source. This looks like the wrong direction in the dependency graph. View components can inject store components, but not the other way around. Any toughts on that?
@@jovanthournout9707 for cases where I want to share some state between a local/private slice and a shared/global slice I would have an imperative action to send that data back to the top of the data flow - specifically what I mean is that in the shared/global service I would have an actionSource (e.g. doTheThing), and then the local service/component can inject the shared service and call that actionSource with the relevant data (e.g. doTheThing(dataFromMyFormSlice))
@@JoshuaMorony Ok, that's what I am also doing. Can't see any other way besides making an imperative call from an effect of one slice to the action source of the other slice. Any idea how state adapt deals with this kind of situation?
The plan currently is to wait for signal based components and then I'll update everything to that, but mostly there isn't much to update just the extra things that came after the v17 release
yes thanks, I'll have try and see if that works here instead of disabling emitEvent (not actually sure since the signal set is being triggered by the valueChanges observable updating)
I've only briefly seen bits and pieces so not enough to comment, and in general I just haven't given template driven forms a proper go yet - I've felt for a long time now that I probably would like template driven forms, but the opportunity to try it out properly just hasn't eventuated
I really love this approach. I do have a question/challenge. How can we use this approach and patch a some data that’s dynamic? For example let’s say you’ve got a form that lets you pick a make and model of a car and on load you want to auto select the last options that the user selected. Also, on change of make you have to get the models of that make from the backend & you need to set the model to null on that change because it wouldn’t make sense to have a “Honda Mustang”. Can something like this with dependent properties and loads be done with signal slice? My past implementations all inevitably have me using afterviewinit and using event emit: true in my patch statement. Also requiring me to check my on change and see if the value of make went from null to a value and if so don’t null model. Hope this makes sense.
At a glance I would think this should be fine - auto applying some previous selected options would likely look similar to what I have in the video, maybe disable the form in the init effect, and load the necessary data as a source + have a side effect via tap to set the data. Then for reacting to changes you might have something like my "requireExplanation" effect, you have all of your form control values available as signals via the selectors, so you can create an effect that runs whenever a particular control value changes - from that effect you should be able to trigger an "actionSource" which can make the call to load the models for that make, and potentially have an "actionEffect" that runs when that "actionSource" emits to handle setting the data in the form + resetting the model back to null. This is all off the top of my head of course so it might require some playing around with - if you do end up trying it and run into any issues feel free to let me know.
That's all cool and interesting but I think you miss the point of reactive forms. You kinda abstract the form-submission away and let your state manage code which by nature does not need declarative behaviour ... your form-submission is always imperative Now what you get as a response you might want react to declarative but I don't see how you make this easier because you basically just smash one abstraction on top of another one and now developers have to deal with both ... reactive forms already manage the state of your form and its formcontrols declarative so I don't really see the merit in this tool except that it is cool
I don't have much to add on outside of what's in the video, but I do find value in having the signalSlice handle all sources of state and being able to derive/react to whatever I need through that - the form submission being a good example of the way it can make things more declarative. As I mentioned though I don't think this is the best abstraction that we can land on specifically for managing forms - signalSlice serves other purposes and happens to integrate in a reasonably convenient way with reactive forms without needing to bring in some other abstraction. I wouldn't advocate for signalSlice as a way to manage forms specifically if you aren't already using it for state management.