2

This is my FormGroup:

this.productGroup = this.fb.group({
  name: ['', Validators.compose([Validators.required, Validators.maxLength(80)])],
  variants: this.fb.array([
    this.fb.group({
      type: '',
      options: this.fb.array([])
    })
  ])
});

How to pass a string array to options? Like this [ 'string1', 'string2' ]. I'm dinamically getting those values here: stackblitz, however i'm not sure how to fill the array. I would like to pass a generic string array directly to options.

variants array example:

variants: [ 
   { type: 'Color', options: ['Red', 'Blue'] },
   { type: 'Size', options: ['Small', 'Medium', 'Big'] }
]

Html:

<form [formGroup]="productGroup">
  <input formControlName="name">
  <div formArrayName="variants" *ngFor="let item of productGroup.controls['variants'].controls; let i = index;">
    <div [formGroupName]="i">
      <mat-form-field>
        <input type="text" placeholder="Variable Type" aria-label="Number" matInput formControlName="type" [matAutocomplete]="auto">
        <mat-autocomplete #auto="matAutocomplete">
          <mat-option *ngFor="let type of types" [value]="type">
            {{type}}
          </mat-option>
        </mat-autocomplete>
      </mat-form-field>
      <mat-form-field>
        <mat-chip-list #chipList>
          <mat-chip *ngFor="let opt of typesOptionsArray[i]" [selectable]="true"
                    [removable]="true" (removed)="removeOpt(opt, i)">
            {{opt}}
            <mat-icon matChipRemove>cancel</mat-icon>
          </mat-chip>
          <input placeholder="Type Options"
                  [matChipInputFor]="chipList"
                  [matChipInputSeparatorKeyCodes]="separatorKeysCodes"
                  [matChipInputAddOnBlur]="true"
                  (matChipInputTokenEnd)="addOpt($event, i)">
        </mat-chip-list>
      </mat-form-field>
    </div>
    <div class="row">
      <a href="javascript:" (click)="addItem()"> Add Variant </a>
      <a href="javascript:" (click)="removeItem(i)" *ngIf="i > 0"> Remove Variant </a>
    </div>
  </div>
</form>
5
  • options values are checkbox in the UI? Commented Nov 3, 2018 at 0:13
  • No, it's Angular Material MatChips. I get a new value everytime a user add a new chip (event), then add it to a string array in my component. Commented Nov 3, 2018 at 0:16
  • @AjayOjha I'm trying this.typesOptionsArray[index].forEach(type => { this.productGroup.controls['variants']['options'].push(new FormControl(type)); }); to pass the string array to FormArray directly Commented Nov 3, 2018 at 0:18
  • can you please share your variants html code ? Commented Nov 3, 2018 at 0:29
  • @AjayOjha there you go. It's kind of complex because of its dynamic generated. Commented Nov 3, 2018 at 0:33

1 Answer 1

5

I have created a sample application on stackblitz for adding array value in the options array.

I would suggest instead of creating FormArray of options field try to create FormControl. I have changed the code of creating FormGroup.

Here is the code of formgroup.

 this.productGroup = this.fb.group({
  name: ['', Validators.compose([Validators.required, Validators.maxLength(80)])],
  variants: this.fb.array([
    this.fb.group({
      type: '',
      options: ''
    })
  ])
});

I have added two methods in the component 'addOption' and 'removeOption' while adding option at that time you need to push a string into the options array.

Here is the code :

let variants = <FormArray>this.productGroup.controls.variants;
let variantFormGroup = <FormGroup>variants.controls[0];
let optionValue = variantFormGroup.controls.options.value;
if(!optionValue)
    optionValue = [];
optionValue.push(`chip${this.currentIndex}`); // push your actutal string value
variantFormGroup.controls.options.setValue(optionValue);

this.currentIndex++; //don't consider this, this is just for adding new name

Here is the code of remove string value from the options array

 let optionValue = this.productGroup.value.variants[0].options;
    if(optionValue.length > 0){
      //let indexOf = optionValue.indexOf(removeValue); find the index number with your value.
      optionValue.splice(0,1);
      let variants = <FormArray>this.productGroup.controls.variants;
      let variantFormGroup = <FormGroup>variants.controls[0];
      variantFormGroup.controls.options.setValue(optionValue);

    }    

here is the json result after adding few values in the options array:

{ "name": "", "variants": [ { "type": "", "options": [ "chip4", "chip5", "chip6", "chip7", "chip8" ] } ] }

please let me know if you have any question.

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

23 Comments

Thank you! I've used a similar approach to save an array of images, but I wasn't sure if it would be possible to apply it dinamically.
Is it possible to store options in a array of objects instead of array: this.productGroup = this.fb.group({ name: ['', Validators.compose([Validators.required, Validators.maxLength(80)])], variants: this.fb.array([ this.fb.group({ type: '', options: this.fb.array([ this.fb.group({ option: '', photos: '' ]) }) ]) });
Yes it is possible, do you need me to design?
Yes... I'm doing something wrong it's always returning an array
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.