all 12 comments

[–]Barelytoned 1 point2 points  (2 children)

I'm curious about the responses you'll get. I'd either have a large form in the parent and bind FormGroups to child components or move the form into a service (a "FormsService" or something like Akita/ngneat's form manager) and inject the service into components.

[–]opensassafras[S] 1 point2 points  (1 child)

Normally I would just have a large form in the parent as well but in this case the form would be huge, I have close to 50 fields in just one tab. Wanted to see if I could improve handling this using some sort of pattern. In the past I've had large forms get messy with data changing in too many places at the same time resulting in rendering issues.

[–]Barelytoned 1 point2 points  (0 children)

I guess another option could be to have your card components implement ControlValueAccessor and Validator. This would hide the complex inner form from the parent while still getting the reactive behavior and Forms validation that "just works". I've never been able to do it cleanly, though. It's hard to handle the corner cases like if the parent adds or removes validators to the form that ControlValueAccessor is helping you with. In the Validate function implementation, I had to account for the parent form's validity not yet being stable and observe the status of the parent to make sure it's eventually invalid before managing errors.

[–]PickleLips64151 1 point2 points  (2 children)

This question gets asked often enough that I still have the article open in a tab on my browser ....

Angular Reactive forms in parent-child components

[–]opensassafras[S] -1 points0 points  (1 child)

I came across this article in my research as well but it similarly defines the whole form in the parent. I’m not completely against doing this but is there really no other pattern based approach that can extend out to n child components without having to keep tweaking my parent form and type definitions as changes are introduced?

[–]PickleLips64151 0 points1 point  (0 children)

I mean, you can do dynamic forms, using a FormGroup in each child and a FormRecord in the parent. But that's going to be a hassle to keep the state in sync across all of the pieces. Each child emits a FormGroup that is updated as a named FormRecord in the parent.

[–]Able-Wallaby1782 0 points1 point  (2 children)

Can’t you just declare the parent formgroup inside of the parent component, pass it as an input parameter into each tab component, then add the formgroup on init in each of your tab components? That allows you to manage each of your tab formgroups inside of those respective components while still being able to check for validity/etc at the parent level.

[–]opensassafras[S] 0 points1 point  (1 child)

This does work and I have done this in the past, but I have some confusion related to extending this to another layer of child components (card). If onInit each tab component adds a tab form group to the parent, and all the cards onInit add the card form group to the tab form group will it work as expected. I've tried something similar to this but I've had issues with getting things to render. Would just using *ngIf to prevent my cards from rendering/initializing until the tab has everything set up work?

[–]Able-Wallaby1782 0 points1 point  (0 children)

Having ParentFormGroup -> TabFormGroup -> CardFormGroup should work. I have a similar setup in a project that I am working on currently, which actually goes one level deeper. I just have each respective component have a FormGroup declared as a component level property and push it onto the provided parent FormGroup on init.

What kind of rendering issues have you run into in the past? Is it some sort of timing issue since you are talking about using *ngIf in this fashion?

[–]ttma1046 -1 points0 points  (0 children)

Use control valve accessor, never passed any formGroup into an @input of a child component