2

I am working with textarea in my component, but my ngModelChange seems not to be working.

<textarea [ngModel]="something?.commentaire" (ngModelChange)="something.commentaire">{{something.commentaire}}

But when I change the commentaire of something in the text area, {{something.commentaire}} doesn't change.

Any idea how could I solve it?

This issue is different from that of two way binding with elvis-operator, because my question is not as regard the elvis operator and how to use it. Rather it is related to the way, the tag textarea handles the changes of event.

edkeveked
  • 17,989
  • 10
  • 55
  • 93
  • I think it could be useful for you to check out template syntax :) https://angular.io/docs/ts/latest/guide/template-syntax.html – AT82 Jun 01 '17 at 10:26
  • @echonax I think this one is slightly different from the one you are referring to. The OP does not know that the `ngModelChange` is emitting the change through the `$event` variable. – borislemke Jun 01 '17 at 10:49
  • @borislemke even if thats true, OP will have this knowledge by looking at the link :-) – eko Jun 01 '17 at 10:50
  • I edited my question to explain in what it is different in comparison with the link @echonax provided – edkeveked Jun 01 '17 at 11:47
  • @edkeveked does the answer of Günter solve your question? – eko Jun 01 '17 at 11:49
  • The answer of Günter doesn't answer my question. Because it doesn't explain the difference when handling the ` ` and when `textarea` is used instead. – edkeveked Jun 01 '17 at 11:57
  • @edkeveked handling `input` and `textarea` is not the issue here. The answer states that you need to assign `$event` to your model plus safe-checking null values with the elvis operator. Even if you just replace `x.y.z` from the answer with your field values, it again gives you the answer.. – eko Jun 02 '17 at 04:33

3 Answers3

3

When using the ngModelChange binding attribute, you want to take the $event data and do something with it.

(ngModelChange)="doSomething($event)"

Above, the $event variable is the change that is emitted from the textarea.

component.ts

    doSomething($event) {

        // Do something with $event, you could for example,
        // convert it to an URL format
        // Imaginery function: "My name is Jeff" => "my-name-is-jeff"
        const uri = makeUri($event)

        // Now you have to set it to the variable you want it to 
        // bind to, so the model gets updated with the new value
        this.something.commentaire = uri
    }

If you don't need to do anything with the data and simply want to bind it to a variable, you can use the "banana in a box" syntax:

[(ngModel)]="something.commentaire"

Note that you cannot use the elvis operator to wait for data to be loaded, else it will break the model binding

[(ngModel)]="something?.commentaire" // Not working!

Under the hood, this syntax is practically replacing:

[ngModel]="something.commentaire" (ngModelChange)="something.commentaire = $event"
borislemke
  • 8,446
  • 5
  • 41
  • 54
1

You could use "banana in the box syntax" for ngModel:

<textarea [(ngModel)]="something.commentaire">{{something.commentaire}}

It is a shortcut that uses ngModelChange under the hood.

But it doesn't work with elvis operator, so you take advantage of $event in the ngModelChange:

<textarea [ngModel]="something?.commentaire" (ngModelChange)="something?.commentaire ? something.commentaire=$event:null">{{something.commentaire}}
Max Koretskyi
  • 101,079
  • 60
  • 333
  • 488
0

Usage of [ngModel] and (ngModelChange) for your need basis is absolutely correct. Only thing you need to do is call a function on (ngModelChange). The event that is emitted by the angular (after model change) stored in the variable $event should be passed to that function. In your case event emitted is of type string which you can assign it to variable something.commentairefrom the method OnChange().

<textarea [ngModel]="something?.commentaire" (ngModelChange)="OnChange($event)">{{something.commentaire}}

OnChange(event : string){
   this.something.commentaire = event;
}
Amit Chigadani
  • 28,482
  • 13
  • 80
  • 98