2

I'm trying to use Angular Material with formGroup in Angular 2 and I have a issue with input validation for nested formControls in differents components.

My problem is: when submitting a form, only the input in the first formGroup get notified that the form has been submitted.

I have created the following exemple:

 @Component({
  selector: 'material-app',
  templateUrl: 'app.component.html'
})
export class AppComponent implements OnInit {
  public myForm: FormGroup;

  constructor(private _fb: FormBuilder) {}

    ngOnInit() {
    this.myForm = this._fb.group({
      nested: this._fb.group({
           id: ['', Validators.required]
      }),
      id: ['', Validators.required],
    });
  }
}

I have a simple formGroup with one nested formController. This is my HTML:

<form [formGroup]="myForm">
  <md-input-container>
    <input mdInput required formControlName="id">
  </md-input-container>
  <other-component [myFormGroup]="myForm" myFormGroupName="nested"></other-component>
  <button md-raised-button type="submit">Rechercher</button>
</form>

The other component just display another input.

I made a plunker to illustrate: http://plnkr.co/edit/WR0cmVOhIfCdkqAVc8xX

You can notice that if I enter a field and quit it right away, the red error line appears on both input. But, if I touch none of the two input and I click on submit, only the non-nested input get underlined. This is because the nested one don't get the information that the form was submitted, even if I pass the formGroup object as a parameter.

Any idea of how can I resolve this problem? How can I make the first input aware of the submitted form?

Thank you a lot !

3
  • In your plunkr, if I click submit and nothing else, I see both inputs underlined in red. Commented Aug 3, 2017 at 15:34
  • For me the plunker does not compile, and the code is different from your question... Commented Aug 3, 2017 at 15:48
  • Yep sorry I update my plunkr as my exemple was actually working. The new plunkr illustrate my problem, validation on submit isnot working in case of nested components Commented Aug 3, 2017 at 16:01

1 Answer 1

2

Angular doesn't add mat-input-invalid class to your nested control. Let's think why?

Here is how class binding for MdInputContainer looks like:

'[class.mat-input-invalid]': '_mdInputChild._isErrorState',

and here is the corresponding style that makes your border red.

.mat-input-invalid .mat-input-ripple {
    background-color: #f44336; // red
}

if you will investigate how _isErrorState property is calculated you can notice that it checks FormGroupDirective.submitted property.

function defaultErrorStateMatcher(control, form) {
    var /** @type {?} */ isSubmitted = form && form.submitted; <----
    return !!(control.invalid && (control.touched || isSubmitted));
}

Since you are creating two FormGroupDirective directives only top-level directive will be submitted.

You can work around it by using reactive FormControlDirective

other.component.ts

@Component({
  selector: 'other-component',
  template: `
      <md-input-container >
        <input mdInput required [formControl]="control">
      </md-input-container>
  `
})
export class OtherComponent  {
  @Input() subname: string;
  @Input() formobj: any;

  control: FormControl;

  ngOnInit() {
    this.control = this.formobj.get([this.subname, 'id'])
  }
}

Plunker Example

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

1 Comment

Thanks Yurzui, It is exactly what I was looking for. The point here is that I need to pass the whole FormGroup object to my nested components instead of passing just the sub FormGroup object. At first I throught passing direcly myForm.get('nested') as a parameter of my other component would do the trick, but no, my nested components needs a reference to the whole formGroup object.

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.