0

I'm trying to create a dynamic reactive form. The user has the ability to choose between either a text (type = 1) input or img (type = 2) input. According to his choice, the right input is being added. - He can add as much input field as he wants.

I've never really used reactive forms before, hence this question.

The code below adds a control according to what module the user has chosen, but for instance adding a textarea only displays a textarea with [object Object] inside - clicking makes it disappear.

Additionally I haven't figured out yet how to submit the form's input. Logging form on submit returns the form, but without the textarea's input.

That's what I have so far:

<form [formGroup]="form" (ngSubmit)="onSubmit()">

    <div *ngFor="let module of form.get('modules').controls; let i = index" class="position-relative" [style.padding-bottom.rem]="paddingValue" (mouseover)="showPaddingInput = true" formArrayName="modules">

      <div class="padding-input position-absolute d-flex justify-content-center" *ngIf="showPaddingInput === true" [style.height.rem]="paddingValue">
        <input type="text" class="align-self-center text-center padding-input-field" [value]="paddingValue" (input)="changePadding(padding.value)" #padding>
      </div>

      <div class="text" *ngIf="module.value.type === 1">
        <textarea class="flow-text" placeholder="Some Text..." rows="3" [formControlName]="i"></textarea>
      </div>

      <div class="img-container" *ngIf="module.value.type === 2">
        <div class="custom-file align-self-center">
          <input type="file" id="i" class="custom-file-input" [formControlName]="i" (change)="handleFileInput($event.target.files)">
          <label class="custom-file-label" for="i"></label>
        </div>
      </div>

    </div>

    <button class="btn btn-dark">Submit</button>

</form>
export class CreateCaseCmsComponent implements OnInit {

  form: FormGroup;

  constructor(private caseService: CasesService) { }

  addModule(type) {
    if (type === 1) {
      const control = new FormControl({type: 1}, Validators.required);
      (this.form.get('modules') as FormArray).push(control);
    } else if (type === 2) {
      const control = new FormControl({type: 2}, Validators.required);
      (this.form.get('modules') as FormArray).push(control);
    }
  }

  ngOnInit() {
    this.form = new FormGroup({
      modules: new FormArray([])
    });
  }

  onSubmit() {
    console.log(this.form);
  }

}

1 Answer 1

1

the first argument to a form control is it's value, so you're setting the initial value as an object and that's why it's showing [object Object] in the text box... that's what you get if you call .toString() on an object, you need to instantiate them like this:

const control = new FormControl('', Validators.required);

or something like that... this affects how you're building your template, so you probably need something more like:

const group = new FormGroup({
   type: new FormControl(1),
   value: new FormControl('', Validators.required)
});

and add that group to your array and access it like:

  <div class="text" *ngIf="module.get('type').value === 1" [formGroupName]="i">
    <textarea class="flow-text" placeholder="Some Text..." rows="3" formControlName="value"></textarea>
  </div>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! Works for me. One more thing though - how do I get this exact array's data on submit?

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.