0

I have a reactiveForm that has a certain number of formArrays. It's like, a product that has a variation, for each variation I add a formArray with a copy of the main formGroup. I can add, delete, view but not edit. When the page loads the values of the last formArray substitutes all others, as if it were some problem with the form having the same name.

I will put the code here:

the template

<div *ngFor="let variation of variations.controls; index as i">
  <div class="collapse" id="variationCollapse{{ i }}">
    <div class="col-lg-12">
       <default-form-box *ngFor="let box of structure.boxes"
             [box]="getTabsOrCommonBox(box)"
             [labels]="structure.labels"
             [rules]="structure.rules"
             [validations]="structure.validations"
             [routes]="structure.routes"
             [formats]="structure.formats"
             [translations]="structure.translations"
             [variation]="structure.variation"
             [isVariation]="false"
             [isUpdate]="true"
             [data]="data.variations[i]"
             [nestedFormGroup]="variationFG"    <---- I guess it's here                                
             [hidden]="!variationService.showBox(structure.variation, box, false)"
                                (notifyValue)="DefaultFormVariationComponent.variationInputItems($event, i)">
                            </default-form-box>
                        </div> 
                    </div>
</div>

the component

private addVariationsForUpdate() {
        if (this.data && this.isUpdateScenario()) {
            if (this.data.variations.length > 0) {
                this.DefaultFormVariationComponent.variationObj = this.data.variations;
                this.DefaultFormVariationComponent.isUpdate = true;
                this.variationService.isUpdate = true;

                for (let i = 0; i < this.data.variations.length; i++) {
                    this.addsVariation(); <--- check here
                }
            }
            return;
        }
        this.DefaultFormVariationComponent.variationObj = [];
    }

the component-in detail

public addsVariation() {
        this.buildVariationForm(); <---- check here
        this.variations.push(this.fb.group(new Variation()));

        this.variationService.index++;
        console.log(this.formGroup.value.variations);
    }

    get variations(): FormArray {
        return this.formGroup.get('variations') as FormArray;
    }

private buildVariationForm() {

        this.variationFG = new FormGroup({}); <--- this is it, each variation has a variationFG as formGroup
        let requiredRules: Object = this.requiredRulesService.prepareRequiredRules(this.structure.rules);
        this.formBuilderService.resetControlFields();
        this.formBuilderService.getFieldsToControls(this.structure.boxes);
        this.reactiveFields = this.formBuilderService.getControlFields();

        for (let reactiveField of this.reactiveFields) {
            this.formBuilderService.build(
                reactiveField.controls,
                this.structure.rules[ reactiveField.field ],
                this.variationFG,
                reactiveField.field,
                this.data
            );
        }
        this.variationFG.validator = this.requiredRulesService
        .requiredValidator(
            requiredRules['required_if'],
            this.formBuilderService
        );
    }

For you guys to have a better ideia of what the problem is, I recorded a short video (17 seconds) to show it to you:

https://drive.google.com/open?id=1AQnIax7BSZEIEyqQwqDDh0L01owt9_j5

On the video I point three variations, each one named "last variation test" + the index of the variation. On the video you can clearly notice that all values were replaced by the last index's values.

Hope I can get any help, if more code is needed I'll surely provide.

Thanks in advance :)

2
  • It is a little bit difficult to find out the root cause of this behaviour, however as you commented on your template I think variationFG coud be one of the reasons of this, since it is not pushed into variants form array so nestedFormGroup will have allways the same value, try to set the nestedFormGroup with a form group that comes from the variants form array using something like variants.at(i) as FormGroup, of course it will require some refactoring on your code. see this example scotch.io/tutorials/… Commented Oct 25, 2018 at 17:52
  • I think the comment bellow, tried to follow our same approach, I tried and it worked fine, thanks, Daniel :) Commented Oct 25, 2018 at 19:48

1 Answer 1

1

Issue

The issue is you using the same FormGroup variationFG for all variations. So whatever you put at the end its reflecting for all.

Fix

You should create separate FormGroup for each variations.

1. Create FormGroup Array

variationFGList = [];

the template

<div *ngFor="let variation of variations.controls; index as i">
  <div class="collapse" id="variationCollapse{{ i }}">
    <div class="col-lg-12">
       <default-form-box *ngFor="let box of structure.boxes"
             [box]="getTabsOrCommonBox(box)"
             [labels]="structure.labels"
             [rules]="structure.rules"
             [validations]="structure.validations"
             [routes]="structure.routes"
             [formats]="structure.formats"
             [translations]="structure.translations"
             [variation]="structure.variation"
             [isVariation]="false"
             [isUpdate]="true"
             [data]="data.variations[i]"
             [nestedFormGroup]="variationFGList[index]" <- Get the FormGroup for variation                                
             [hidden]="!variationService.showBox(structure.variation, box, false)"
                                (notifyValue)="DefaultFormVariationComponent.variationInputItems($event, i)">
                            </default-form-box>
                        </div> 
                    </div>
</div>

the component-in detail

private buildVariationForm() {

        let variationFG = new FormGroup({}); //this is local variable now
        let requiredRules: Object = this.requiredRulesService.prepareRequiredRules(this.structure.rules);
        this.formBuilderService.resetControlFields();
        this.formBuilderService.getFieldsToControls(this.structure.boxes);
        this.reactiveFields = this.formBuilderService.getControlFields();

        for (let reactiveField of this.reactiveFields) {
            this.formBuilderService.build(
                reactiveField.controls,
                this.structure.rules[ reactiveField.field ],
                 variationFG,
                reactiveField.field,
                this.data
            );
        }
        variationFG.validator = this.requiredRulesService
        .requiredValidator(
            requiredRules['required_if'],
            this.formBuilderService
        );
        this.variationFGList.push(variationFG); //Add new formGroup to the Array
    }

NOTE : The code was modified in stackoverflow editor so there could be typo and syntactical error. Please correct yourself.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, Sunil! That was exactly it! You helped a lot!

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.