1

I have a dynamic form where I can add more elements.

<form [formGroup]="_formWorkout">
    <div *ngIf="_id>0">
        <!--workouts-->
        <div formArrayName="workouts">
          <div *ngFor="let workout of _formWorkout.controls.workouts.controls; let i=index" class="panel panel-default">
            <div class="panel-heading">
              <span>Workout {{i + 1}}</span>
              <span class="glyphicon glyphicon-remove pull-right" *ngIf="_formWorkout.controls.workouts.controls.length > 1" (click)="removeWorkout(i)">x</span>
            </div>
            <div class="panel-body" [formGroupName]="i">
              <div class="form-group">
                <label>name {{workout |json}}</label>
                <input type="text" class="form-control" formControlName="name">
                <app-field-error-display [displayError]="formValidationService.IsFieldInvalid(_formWorkout,['workouts', i, 'name'],'required')"
                  errorMsg="Field is required"></app-field-error-display>
              </div>
              <div class="form-group">
                <label>description</label>
                <input type="text" class="form-control" formControlName="description">
                <app-field-error-display [displayError]="formValidationService.IsFieldInvalid(_formWorkout,['workouts', i, 'description'],'required')"
                  errorMsg="Field is required"></app-field-error-display>
              </div>
              <div class="form-group">
                  <a (click)="kempe(workout)" style="cursor: default">
                      Save
                    </a>
                    <button (click)="kempe(workout)" class="btn btn-primary">{{_submitButtonText}}</button>
                </div>
            </div>
          </div>
        </div>
        <div class="margin-20">
          <a (click)="addWorkout()" style="cursor: default">
            Add another workout +
          </a>
        </div>
      </div>
    </form>

This is form in component:

this._formWorkout = this._formBuilderWorkout.group({
    workouts: this._formBuilder.array([
    ])
});

I don't have luck accessing workout element inside of *ngFor and the way to pass model workout to kempe function.

I want to save workout element for each. As you can see how can I pass each element for itself to api instead of all collection: enter image description here

1 Answer 1

4

You can access your array by using get method, then the FormArray method at to access it

i.e.

control = <FormArray>this.formWorkout.get('workouts')
console.log(contol.at(0));

or quicker

console.log( (<FormArray>this.formWorkout.get('workouts')).at(0));

and if you want just the value, and not the form group

console.log( (<FormArray>this.formWorkout.get('workouts')).at(0).value);

Regarding your reactive form, I prefer to use the FormGroup, FormArray and FormControl constructor to know exactly where I'm assigning what, but this will help you get going

.component

.html

<form [formGroup]="formWorkout" (ngSubmit)="onSubmit()">
  <div formArrayName="workouts">
    <div
            *ngFor="let workout of formWorkout.get('workouts').controls;  let i=index"
            class="panel panel-default"
            [formGroupName]="i">
      <div class="panel-heading">
        <span>Workout {{i + 1}}</span>
      </div>
      <div class="panel-body">
        <div class="form-group">
          <!--<label>name {{workout |json}}</label>-->
          <input type="text" class="form-control" formControlName="name">
        </div>
        <div class="form-group">
          <label>description</label>
          <input type="text" class="form-control" formControlName="description">
        </div>
      </div>
      <button class="btn btn-danger" type="button" (click)="removeWorkout(i)">
        x
      </button>
      <button class="btn btn-primary" (click)="indexSelected=i" type="submit" style="cursor: default">Save</button>
    </div>
  </div>

  <div class="margin-20">
    <button class="btn btn-primary" type="button" (click)="addWorkout()" style="cursor: default">
      Add another workout +
    </button>
  </div>
</form>

.ts

formWorkout: FormGroup;
indexSelected = 0;

  constructor() {}

  ngOnInit() {

    // Create our form group, and feed it the form control,
    // in this case just a workout array
    this.formWorkout = new FormGroup( {
      'workouts' : new FormArray([
        // Instantiate one
        new FormGroup({
          'name': new FormControl(''),
          'description': new FormControl('')
        })
      ])
    });

  }

  addWorkout() {
    (<FormArray>this.formWorkout.get('workouts')).push(
      new FormGroup({
        'name': new FormControl(''),
        'description': new FormControl(''),
      })
    )
  }

  removeWorkout(index: number) {
    (<FormArray>this.formWorkout.get('workouts')).removeAt(index);
  }

  onSubmit() {
    console.log( (<FormArray>this.formWorkout.get('workouts')).at(this.indexSelected).value);
  }

If you feed submit here an index argument, it should be able to give you enough information so you can index the form group array and get the corresponding values

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

2 Comments

bro this wont work. this only has one save button, i need multiple saves for each element. i already figured it out, ill post answer later.
amels can you post answer

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.