3

I am trying to bind a form item to an object without using ngModel. But it is not working.

I tried using the [(value)]="" attribute. However, the initial value of the element changed to "undefined".

https://material.angular.io/components/input/overview

<mat-form-field class="col-md-4">
    <input matInput placeholder="First name" formControlName="firstCtrl" [(value)]="formData.firstName">
    <mat-error>First name can not be left blank</mat-error>
</mat-form-field>

formData = new RawFormData;

But this one is working correctly:

<mat-form-field>
    <mat-select placeholder="Title" formControlName="titleCtrl" [(value)]="formData.gender">
          <mat-option *ngFor="let title of personalTitle" [value]="title.value">{{title.viewValue}}</mat-option>
    </mat-select>
</mat-form-field>
Sanoj_V
  • 2,936
  • 1
  • 12
  • 28
radeveloper
  • 926
  • 2
  • 12
  • 20
  • 1
    Use ngModel for two-way binding. What's problem with ngModel. Post error – Shashikant Devani Sep 17 '18 at 13:03
  • If you need tow way binding try this: https://stackoverflow.com/questions/52290322/implement-two-way-data-binding-for-custom-property/52290689#52290689 – Dmitriy Snitko Sep 17 '18 at 13:05
  • The problem with ngModel is: It looks like you're using ngModel on the same form field as formControlName. Support for using the ngModel input property and ngModelChange event with reactive form directives has been deprecated in Angular v6 and will be removed in Angular v7. For more information on this, see our API docs here: https://angular.io/api/forms/FormControlName#use-with-ngmodel – radeveloper Sep 17 '18 at 13:10
  • Just set its default value in the backend when you create the formGroup `firstCtrl: ['Foo']`, or update its value after you get the required data. `myForm.get('firstCtrl').setValue('Foo');`. – Joseph Webber Sep 17 '18 at 13:10
  • So you're saying if you use angular materials, you lose two way binding without extra coding? – radeveloper Sep 17 '18 at 13:23
  • No, it means you have to use either reactive forms (which uses formControlName) or ngModel. I think the big question is, why do you want to use both? – tom van green Sep 17 '18 at 14:03
  • Tom! I think you're in the wrong title. Or I wrote the question wrong – radeveloper Sep 17 '18 at 14:44
  • Please check out the SlimenTN's answer to realize the problem. – radeveloper Sep 17 '18 at 14:50

2 Answers2

3

value of the input is predefined html attribute and does not emit changes.
In the other hand mat-select is a custom angular component where they declared value as input and output at the same time, something like this:

@Input('value') input: any;
@Output('value') output: EventEmitter;

That's why you can bind it in both ways.
so in your case either you work with ngModel or do something like this:

<input (change)="inputValue = $event.target.value" [value]="inputValue"/>
SlimenTN
  • 3,383
  • 7
  • 31
  • 78
  • In that way it's getting "undefined" expression as a default value in form element. So i have to initialize it first. Is that possible to bind it without initialize it – radeveloper Sep 17 '18 at 13:06
  • of course you need to initialize the value `inputValue: string = '';` – SlimenTN Sep 17 '18 at 13:11
  • Yet it is not the ideal solution imo, but I have to choose this one for now. Thanks by the way. – radeveloper Sep 18 '18 at 10:47
2

The only way that comes to my mind of doing it without [ngModel] is to use (keyup). I would try to change your input to something like this:

<mat-form-field class="col-md-4">
          <input matInput placeholder="First name" formControlName="firstCtrl" (keyup)="onKey($event)">
          <mat-error>First name can not be left blank</mat-error>
        </mat-form-field>

and then add a function

onKey(event: any) { // without type info
    formData.gender = event.target.value;
  }
hjbello
  • 643
  • 4
  • 18