angular 6 deprecation of using formControlName and ngModel together

17,437

Solution 1

Having ngModel with formGroup is really odd. You should remove ngModel and instead bind on valueChanges on fromGroup and then just iterate through received data and assign values.

 //somewhere where form is build
 this.studentForm.valueChanges.subscribe(data => this.onStudentFormValueChange(data));

 private onStudentFormValueChange(data) {
    this.selectedStudent.age = data.age
    this.selectedStudent.email = data.email
    this.selectedStudent.nameSurname = data.nameSurname

    // or
    for (const key in this.studentForm.controls) {
       const control = this.studentForm.get(key);
       this.selectedStudent[key] = control.value
    }
}

Solution 2

You just choose either ngModel with mean you are using template driven form or formControlName with mean you are using reactive form. https://angular.io/guide/reactive-forms If you want a simple form just remove formControlName in every input. If you want to do more in form you can use reactive form by remove ngModel and add name attribute like name=nameSurname

Solution 3

There is no need to use both (ngModel and formControlName)

While Update you can use reactive form using

 patchValue(value: {...}, options: {...}): void

https://angular.io/api/forms/FormGroup

For your case you will need something like

this.studentForm.patchValue({
  nameSurname : 'Some Name',
  email : '[email protected],
  age : '24'
})

This will pre-fill the value to the form and you can easily use same form for update

Share:
17,437
realist
Author by

realist

Updated on July 13, 2022

Comments

  • realist
    realist almost 2 years

    I have angular 6 project. And I was using ngModel and formControlName together. But angular gave me warning in below. Forexamle when I open update popup from button in grid, I can easily bind inputs in update popup automatically. But angular 7 says that remove ngModel. So, I must always map everything to my student object. What is the best way for this? Can we give formValueType to form value like studentObject in below code and then can it bind automatically?

    Angular warning:

         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.
    

    myHtml

    <form [formGroup]="studentForm" ??????formValueType="studentObject"?????>
      <p-dialog>
        <div class="ui-g-12 form-group">
          <div class="ui-g-4">
            <label>Name Surname</label>
          </div>
          <div class="ui-g-8">
            <input pInputText [(ngModel)]="selectedStudent.nameSurname"  formControlName="nameSurname" />
          </div>
        </div>
        <div class="ui-g-12 form-group">
          <div class="ui-g-4">
            <label>Email</label>
          </div>
          <div class="ui-g-8">
            <input pInputText [(ngModel)]="selectedStudent.email" formControlName="email" />
          </div>
        </div>
            <div class="ui-g-12 form-group">
              <div class="ui-g-4">
                <label>Age</label>
              </div>
              <div class="ui-g-8">
                <input pInputText [(ngModel)]="selectedStudent.age"  formControlName="age" />
              </div>
            </div>
          </div>
        <button type="button" pButton icon="fa fa-check" (click)="save()" label="Save"></button>
      </p-dialog>
    </form>
    
  • realist
    realist over 5 years
    Thanks for your reply. But in this example, there are only three input at the page. But in real scenario, there are more than 50 input. And mapping all these properties is very big work for all page. But when i'm using ngModel it bind automatically. How can i bind automatically? @KrutiChoksiPatel
  • realist
    realist over 5 years
    Thanks for your reply. Using template driven form is very easy and everything be automatically. But, in that i can't validation. Using reactive form is very difficult and wirting more and more code.But, I understand from the replies, in future template driven won't be used. And technology will continue with reactive forms. Is it true? Because i 'm starting new project and i must choose one of them. @K.tin
  • HDJEMAI
    HDJEMAI over 5 years
    How to deal with initial values this way ? assign initial values ? I think this will not auto bind the initial values for input , select, ...
  • AT82
    AT82 over 5 years
    @HasanOzdemir Of course you can have validation on a template driven form: angular.io/guide/form-validation But I'd go for a reactive form though :)
  • realist
    realist over 5 years
    If I start with reactive form to project, then i mustn't use template driven anywhere in project. In other words, some pages reactive some pages template driven (hybrid) is not good. Is it true? @AJT_82
  • AT82
    AT82 over 5 years
    @HasanOzdemir Yes, you cannot (in future) mix template driven and reactive form in the same. I'm so happy that this deprecation warning exists now, since people have been "misusing" this way too much ;) But you can use either reactive form or template driven form, just don't use them in same form :)
  • realist
    realist over 5 years
    I will start a big project with reactive form. But is this usage have any problem which @HDJEMAI says. Or any other problem?
  • realist
    realist over 5 years
    Thanks for your reply @AJT_82. My last question is: I decided that all forms in my project will be reactive form. And reporting and dataGrid page will be template driven in my project. I think, this is the best way. Am i right?
  • Patryk Brejdak
    Patryk Brejdak over 5 years
    You mean initialy bind values to selectedStudent or studentForm?
  • realist
    realist over 5 years
    Bind to studentForm @PatrykBrejdak
  • Patryk Brejdak
    Patryk Brejdak over 5 years
    No, it won't assign intial values to studentForm since it's just copying values for selectedStudent from studentForm controls. My bad, I misunderstood your question, it actually depends how your form is build. @HasanOzdemir could you show how you build your form? Are you rebuilding form whenever you switch selectedStudent?
  • HDJEMAI
    HDJEMAI over 5 years
    @K.tin: can you explain how to get 2 way data binding by using only formControlName and populating each input to an object property for example ? I think you have to go deep in your answer. binding initial values should work in the same time for any type of input.
  • AT82
    AT82 over 5 years
    @HasanOzdemir You can choose however you want, what suits your needs best! :)
  • K.tin
    K.tin over 5 years
    @HDJEMAI You can use valueChanges in reactive form and parse the value in form to an object. Here is my example: github.com/dnkTin/testgithub/blob/master/…
  • realist
    realist over 5 years
    I have showModal function. And I call when click update button in dataGrid. And It send selected student information as parameter and open modal. I'm only wrote this function and then every property automatically bound. My function is: showModal(student: Student){ this.selectedStudent = Object.assign({}, student);} . This was template driven form. So, it can be done easily. But, I will change to reactive form. Because every answer in that post suggest reactive form. I always use template driven. So, i don't know how i build my form. I will try :) @PatrykBrejdak
  • Patryk Brejdak
    Patryk Brejdak over 5 years
    coryrylan.com/blog/… this should be good start point
  • Patryk Brejdak
    Patryk Brejdak over 5 years
  • Kruti Choksi Patel
    Kruti Choksi Patel over 5 years
    { nameSurname : 'Some Name', email : '[email protected], age : '24' } Yes this object can be obtained by for loop of keys
  • Erik Ostermueller
    Erik Ostermueller over 3 years
    What is the data type of 'data'?
  • Patryk Brejdak
    Patryk Brejdak over 3 years
    It actually depends on form controls structure, for example structure for controls used in question would be object { nameSurname: "some_string", email: "some_string", age: "some_string" }.