store icon indicating copy to clipboard operation
store copied to clipboard

🐞[BUG]: NGXS Forms Plugin - Sub Form with Dynamic Fields - 2 way binding not working.

Open dinbtechit opened this issue 3 years ago • 1 comments

Description

I am not sure if this is a bug or if I am doing it wrong.

NGXS Forms Plugin 2-way binding is not working for subforms with dynamically created fields. Not sure how to transfer the state from parentFrom . The fields that are created in the sub form simply overwrites the state to null.

sub-form.component.ts

  ngOnInit() {
    this.parentForm = this.parentControl.control.get('child');
    // Dynamic Child Field.
    this.parentForm.addControl('childName', new FormControl());
  }

image

🔬 Minimal Reproduction

Take a look at the stackbliz

https://stackblitz.com/edit/ngxs-forms-plugin-simple-example-oyfci1?file=src/app/app.component.ts

Environment


Libs:
- @angular/core version: 11.x.x
- @ngxs/store version: 3.7.X
 

dinbtechit avatar Apr 13 '22 20:04 dinbtechit

Any updates on this one?

dinbtechit avatar Jun 04 '22 18:06 dinbtechit

Sorry for the late response, but I only got my hands on that issue. In your example, the child control is added dynamically, meaning it doesn't exist when the form is initialized. The state value gets overridden by child: {} and then child: { childName: null }. I'm not sure to consider this a bug since the form plugin implementation is supposed to sync the state whenever the valueChanges emits and vice versa (sync the form when the state changes).

I don't have deep experience with the form plugin since I don't use it in any app, so I can't advise on the best way to fix it. If you declare child control when initializing the form (child: this.fb.group({ childName: [] }), then the current state will equal the expected state.

arturovt avatar Nov 13 '22 21:11 arturovt

No worries. I appreciate the response. But the workaround you proposed is precisely what I am doing right now—initializing all child controls when the form is initialized.

Although, I think it could be a good feature. If the ngxs-form plugin could dynamically add child controls. Dynamic forms are such a common thing these days.

dinbtechit avatar Nov 13 '22 21:11 dinbtechit

I ain't sure what you mean by If the ngxs-form plugin could dynamically add child controls. The form plugin's responsibility is to sync the state, and the form group model is created and handled by users. The only ability to observe changes is to listen to valueChanges which gives the exact value the form reflects. This leads to side effects when form value and state are not in sync because it causes read-write conflicts. The only way to keep the initial value is to persist it before the form is created and synced with the state:

<app-sub-form [initialChildName]="initialChildName"></app-sub-form>

form = this.fb.group({
    parentName: [''],
    child: this.fb.group({}),
  });

initialChildName = this.store.selectSnapshot(FormState).model.child.childName;

// sub-form
@Input() initialChildName;

this.parentForm.addControl('childName', new FormControl(this.initialChildName));

arturovt avatar Nov 13 '22 21:11 arturovt

I ain't sure what you mean by If the ngxs-form plugin could dynamically add child controls

I meant it would be nice if the plugin could somehow include the state of the dynamically added child controls.

Actually, the code example makes more sense. Thank you. I appreciate it.

dinbtechit avatar Nov 13 '22 21:11 dinbtechit