DEV Community

Cover image for Angular NgModel : Model, ViewModel and Pipes
John Peters
John Peters

Posted on • Updated on

Angular NgModel : Model, ViewModel and Pipes

Today's focus is on the ngModelChange event. This event is an @Output event on the ngModel directive.

The code below is using a select element for picking a City. The options presented to the user are a list of all Cities in any given State.

The bindings for the select element are shown below.

  // the ngModel traid for 2 way data binding
  #city="ngModel"
  [(ngModel)]="address.city"
  (ngModelChange)=
    "address.city = onPropertyChange(city)"
Enter fullscreen mode Exit fullscreen mode
  onPropertyChange(city) {
      return city.viweModel;    
   }
Enter fullscreen mode Exit fullscreen mode

The triad of #city,[(ngModel)] and (ngModelChange) allow for two-way binding. When onProperyChange fires the ngModel named city is seen.

When our input control first loads, the ngModel is bound to the address.city property. The default value for address.city is "undefined". After the user makes a selection, this is what is shown for the NgModel.

Alt Text

viewModel

The 'viewModel' exposes the current change. It's the same value as is found in the control's value property and always tracks that value.

  • The "control" being an automatic instance of the Angular FormControl.
  • The 'viewModel' property is easier to use than to go into the control.value property.

model

In the image above we see a value of "undefined" for the "model" property. The model property is always the "last" known value for the binding. A nice way to revert changes should something go wrong.

Using Pipes

ngModelChange will always fire before the pipe does. Here we add a pipe named 'cityPipe'

  #city ="ngModel"
  [ngModel]="address.city | cityPipe"
  (ngModelChange)=
    "address.city=
       onPropertyChange(city)"  

Enter fullscreen mode Exit fullscreen mode
  • #city is the name of the control which has a value of the ngModel instance.
  • The onPropertyChange function allows us to do other things before returning a value for the address.city assignment.
  • The address.city value becomes the value returned from the onPropertyChange function.
  • After onPropertyChange returns; the Pipe named cityPipe is called.

Note: Don't set address.city in the onChange function as it will cause an endless loop of onChange events. Rather set address.city as shown above.

Changes made via the pipe will not re-fire the NgModel Change event! This allows the actual value of address.city to be different than the displayed post-pipe action. This is especially useful for hiding values in the view.

Next up: Using Validation Patterns with ngModel.

JWP2020 model viewmodel ngModel binding

Top comments (1)

Collapse
 
jangelodev profile image
João Angelo

Hi John Peters,
Your tips are very useful
Thanks for sharing