8

I'm currently working on an angular 5 application. I try to alter a member variable of my component in an input on the view and use the variable in my component after the change.

My structure is as follows:

Folder: my-test

  • my-test.component.html
  • my-test.component.css
  • my-test.component.ts

1) my-test.component.html:

<input [(ngModel)]="hello" />

2) my-test.component.ts:

import { Component, OnChanges, SimpleChanges } from '@angular/core';

@Component({
  selector: 'my-test',
  templateUrl: './my-test.component.html',
  styleUrls: ['./my-test.component.css']
})
export class MyTestComponent implements OnChanges {
  hello: string = "bonjour";

  constructor() { }

  ngOnChanges(changes: SimpleChanges) {
    // I'd like to log the changes of my field 'hello', 
    // once it get's changed in the input on the ui...

       console.log(changes);
  }

}

Unfortunately this solution doesn't work. Do you know how to change an component's variable on the ui and use it in the component afterwards?

Thank you!!

TimHorton
  • 797
  • 3
  • 10
  • 28
  • 2
    You are misunderstanding the use of OnChanges, it is fired when changes happen to a @Input. Instead of "banana in the box", i.e `[(ngModel)]` use `[ngModel]` and `(ngModelChange)` which the banana in the box is shorthand of :) – AJT82 Mar 22 '18 at 18:46
  • 1
    thanks for the clearification :) – TimHorton Mar 22 '18 at 19:33

3 Answers3

8

you can use the (ngModelChange) directive

    <input [(ngModel)]="hello" (ngModelChange)="myFunction()"/>

code:

    import { Component } from '@angular/core';

    @Component({
        selector: 'my-test',
        templateUrl: './my-test.component.html',
        styleUrls: ['./my-test.component.css']
    })
    export class MyTestComponent {
        hello: string = "bonjour";

        constructor() { }

        myFunction() {
            console.log(this.hello);
        }
    }
Matt
  • 1,613
  • 7
  • 17
  • `ngModelChange` is not a directive, it's an `@Output` property associated with `NgModel` directive which emits every time the value of `ngModel` changes. – Nikx Fabrizio Nov 04 '19 at 05:48
1

You can use (ngModelChange)=functionToCall($event) to call the function on model change and get updated value. It's pretty useful, and you can use it with regular [(ngModel)] on the same element. In this case you can use just [ngModel] instead of regular [(ngModel)] and set new value to variable from functionToCall function, but it depends on your needs. Here is a small demo (check the console to see updated values):

https://stackblitz.com/edit/angular4-rnvmhm?file=app%2Fapp.component.html

Commercial Suicide
  • 13,616
  • 13
  • 48
  • 72
1

Use the banana in the box syntax [(ngModel)] to get the two way data binding for your variable(hello), if you just want to use the hello variable in some other method inside the component then there's no need to watch the value change manually, because ngModel will keep property(hello) and view(input) in sync, so methods using 'hello' property will always get the updated value.

But if you want to do something on every time the value changes then use ngModelChange property to listen for the value change of the property.

<input type="text" [(ngModel)]="hello">
{{hello}}

listen for change in value of the property

<input type="text" [(ngModel)]="hello" (ngModelChange)="executeCallback($event)">
{{hello}} //will also get updated

<input type="text" [ngModel]="hello" (ngModelChange)="executeCallback($event)">
{{hello}} //will not get updated
Nikx Fabrizio
  • 120
  • 1
  • 6
  • In case you want to invoke the same function every time the model changed - regardless of what attribute of the model has changed - isn't there a simpler method than callling a (ngModelChange) for every form element? – feder Oct 31 '19 at 21:07
  • @feder you can utilize lifecycle hooks (i.e ngDoCheck, ngOnChanges) managed by Angular here. – Nikx Fabrizio Nov 04 '19 at 05:54