0

I am building a Reactive Form (edit/new) in Angular 12 which contains a Form Array called 'actions'. I have the Form working to submit new and update existing multiple items in the Array. The problem I have is when the edit form loads in the browser, only the first array item is displaying. The multiple items in the array are definitely being retrieved, just not displaying. Here is the code:

component.ts file

export class AdviceEditComponent implements OnInit {
id: number;
isAddMode: boolean;
adviceForm: FormGroup;
validationErrors: string[] = [];
actions: FormArray;

constructor(private route: ActivatedRoute,
            private adviceService: AdviceService,
            private router: Router, private fb: FormBuilder) {              
}

ngOnInit() {
  this.id = this.route.snapshot.params['id'];
      this.isAddMode = !this.id;

      this.adviceForm = this.fb.group({
        title: ['', Validators.required],
        description: ['', Validators.required],
        sourceUrl: ['', Validators.required],
        actions: this.fb.array([this.createAction()]) 
    });

    if (!this.isAddMode) {
        this.adviceService.getAdvice(this.id)
            .pipe(first())
            .subscribe(x => this.adviceForm.patchValue(x));
    }
}

createAction(): FormGroup {
  return this.fb.group({
    id: '0',
    what: '',
    how: ''
  });
}

get controls() { // a getter!
  return (<FormArray>this.adviceForm.get('actions')).controls;
}

onAddAction(): void {
  this.actions = this.adviceForm.get('actions') as FormArray;
  this.actions.push(this.createAction());
}
}

component.html file

<div class="row">
  <div class="col-sm-12">
    <form [formGroup]="adviceForm" (ngSubmit)="onSubmit()">
      <div class="row">
        <div class="col-sm-10">
          <div class="form-group">
            <label for="title">Title</label>
            <input type="text" id="title" formControlName="title" class="form-control">
            <span *ngIf="!adviceForm.get('title').valid && adviceForm.get('title').touched" class="help-block">
              Please enter a Title
            </span>

          </div>
        </div>
      </div>
      <div class="row">
        <div class="col-sm-10">
          <div class="form-group">
            <label for="description">Description</label>
            <textarea type="text" id="description" formControlName="description" class="form-control"
              rows="6"></textarea>
            <span *ngIf="!adviceForm.get('description').valid && adviceForm.get('description').touched"
              class="help-block">
              Please enter a Description
            </span>
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-sm-10">
          <div class="form-group">
            <label for="sourceUrl">Source Url</label>
            <input type="text" id="sourceUrl" class="form-control" formControlName="sourceUrl">
            <span *ngIf="!adviceForm.get('sourceUrl').valid && adviceForm.get('sourceUrl').touched" class="help-block">
              Please enter a Source Url
            </span>
          </div>
        </div>
      </div>

      <div class="row">
        <div class="col-xs-12" formArrayName="actions">
          <div class="row" *ngFor="let action of adviceForm.get('actions')['controls']; let i = index" [formGroupName]="i"
            style="margin-top: 10px; margin-left: 15px;">

            <div class="col-xs-8 mr-2">
              <input type="text" class="form-control" formControlName="what">
            </div>

            <div class="col-xs-2 mr-2">
              <input type="text" class="form-control" formControlName="how">
            </div>
            <div class="col-xs-2">
              <button class="btn btn-danger">X</button>
            </div>
          </div>
          <hr class="ml-3">
          <div class="row">
            <div class="col-xs-12 ml-5">
              <button type="button" class="btn btn-success" (click)="onAddAction()">Add Action</button>
            </div>
          </div>

        </div>
      </div>
      <div class="row">
        <div class="col-sm-12 mt-3 ml-3">
          <button type="submit" class="btn btn-success mr-2" [disabled]="!adviceForm.valid">Save</button>
          <button type="button" class="btn btn-danger" (click)="onCancel()">Cancel</button>
        </div>
      </div>
    </form>
  </div>
</div>

I have been struggling to solve this for hours and I just cannot see what I am doing incorrectly. Any help would be greatly appreciated. Thank you.

1 Answer 1

1

.patchValue() will update the existing FormArray. It will not create or delete the item from array. Here you are having only one item in the actions formArray.

Please try below code.

        this.adviceService.getAdvice(this.id)
            .pipe(first())
            .subscribe(x => {
                const actions = this.adviceForm.get('actions') as FormArray;
                actions.clear();
                x.actions.map(action => actions.push(this.createAction()))
                this.adviceForm.patchValue(x)
             });
Sign up to request clarification or add additional context in comments.

Comments

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.