1

First of all, I've read a lot of stackoverflow's answers about nested forms but I couldn't fix my problem with those, thanks for your time.

I'm trying to do a form to edit user's information, the information I use is something like that:

(2) [Object, Object]
  0: Object
    mail: "example1@exp.exp"
  1: Object
    mail: "example2@exp.exp"

In my component I create a nested form:

// blablabla.component.ts

// imports, component, ...

export class EditMailsComponent implements OnInit {
  @Input() data: Array<any>;

  private form: FormGroup;

  constructor(
    private formBuilder: FormBuilder
  )

  ngOnInit(){
    this.form = this.formBuilder.group({
      mails: this.formBuilder.array([]),
    });

    this.fnOpen();
  }

  private fnOpen()
  {
    // ...

    const control = <FormArray>this.form.controls['mails'];

    this.data.forEach(x => {
      control.push(this.populateForm(x);
    });

    // ...
  }

  private populateForm(x: Array<any>)
  {
    return this.formBuilder.group({
      mail: [x.mail]
    });
  }
}

And my html file looks like this:

<!-- ... -->
<form class='smart-form' novalidate>
  <div class='modal-body'>
    <div [formGroup]='form'>
      <div formArrayName='mails'>
        <div *ngFor='let mail of form.controls.mails.controls; let i=index'>
          <div [formGroupName]="i">
            <fieldset>
              <section class='col-col-6'>
                <label class='input' id='mail'>
                  <input type='text' formControlName='mail' ngModel>
                </label>
              </section>
            </fieldset>
      <!-- ... --> 

When I try to open the page to edit, the correct number of nested forms are created (ex: if i have a 4 object array, 4 forms are opened) but "mail" is not displayed in .

Could someone tell me where I'm missing?

If you need any more information, I'll be glad to help.


Update:

Places I've visited before ask:

  1. STACKOVERFLOW - Angular 2 Form “Cannot find control with path”
  2. STACKOVERFLOW - Angular 2 Form “Cannot Find Control”
  3. STACKOVERFLOW - Cannot find control with path: angular2
  4. STACKOVERFLOW - Angular 2 Accessing Nested FormArrays using FormBuilder

Tutorials (I tried to use those to find the error in my code):

  1. How to Build Nested Model-driven Forms in Angular 2
  2. Angular2: Building nested, reactive forms
criw
  • 587
  • 1
  • 5
  • 15
  • you could add the links to the questions you have looked at :) and is there a reason for `ngModel` on your input? it is not required in a reactive form. Also would it be possible to provide a live example? [Here's a plunker template you could start with](https://plnkr.co/edit/tpl:AvJOMERrnz94ekVua0u5) – 0mpurdy Jul 24 '17 at 00:29
  • There you have the links! And I didn't know that ngModel wasn't needed, I'll try without it. Also I'll try to provide a example; thanks! – criw Jul 24 '17 at 00:39
  • Could you clarify your data structure is it an object or an array? `{0: {mail: "example1@exp.exp"}, 1: {mail: "example2@exp.exp"}}` or `[{mail: "example1@exp.exp"}, {mail: "example2@exp.exp"}]`? I'll assume an array as I try to answer for now – 0mpurdy Jul 24 '17 at 07:11
  • Also do you need the mails to be grouped in a child component or would a structure like in the first tutorial you tried be sufficient? – 0mpurdy Jul 24 '17 at 07:37
  • data is supposed to be a array. And I would prefer something like in the first tutorial, without having to create a child component, thanks! – criw Jul 24 '17 at 10:37

1 Answers1

1

Using data in the structure:

[
  {
    "mail": "example1@exp.exp"
  },
  {
    "mail": "example2@exp.exp"
  }
]

parent component

ngOnInit() {
    this.myForm = this._fb.group({
        name: ['', [Validators.required, Validators.minLength(5)]],
        mails: this._fb.array(this.mails.map(mail => this._fb.group(mail)))
    });
}

parent template

<form [formGroup]="myForm" novalidate (ngSubmit)="save(myForm)">
  <ng-container *ngFor="let mail of myForm.controls.mails.controls">
    <mail [group]="mail"></mail>
  </ng-container>
</form>

child component

@Component({
  moduleId: module.id,
  selector: 'mail',
  templateUrl: 'mail.component.html',
})
export class MailComponent {
  @Input('group')
  public mailForm: FormGroup;
}

child template

<div [formGroup]="mailForm">
  <div class="form-group">
    <label>mail</label>
    <input type="text" class="form-control" formControlName="mail">
  </div>
</div>

Live plunker example

0mpurdy
  • 3,198
  • 1
  • 19
  • 28
  • Thanks, it seems there was a mistake in my html with ngModel, but now it's working! – criw Jul 24 '17 at 12:15