Angular – Not Detecting Change, Updating Variable When Model Passed in Method as Param

Declaring a model value in the template, then passing it as a reference in method params, does not detect the updated model value; We are going to discuss this issue in detail and also the ways to resolve it with a simple use-case.

This Angular post is compatible with Angular 4 upto latest versions, Angular 7, Angular 8, Angular 9, Angular 10, Angular 11 & Angular 12

In the Angular app, we need to make changes in local variables which are getting used and defined as global. These variable or Model values does not reflect any change if we pass them as argument or parameter in a component method, then change in that parameter value does not reflect globally in view.

When we pass the model/ variable value as param in the method, they become local to that methods inner scope and loses their reference to the actual variable.

Let’s understand this with an application having two versions:

First Use-Case

In this use case, we have defined a boolean variable in the App component class named isWorkingset . In the constructor setting its value to false.

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  
  isWorking:boolean;

  constructor() {
	//Initialize value to false
    this.isWorking = false;
  }
  changeValue(booleanValue){
    //Converting true to false or false to true
	booleanValue = !booleanValue;
  }
}

Now, let’s show this value in view and a click event calling a method to change its value from false to true. But you will realize this value is not changing.

<div (click)="changeValue(isWorking)">
      {{isWorking}} 
</div>

Solution 1

In this case, the only option left is to change of global variable instead of a local variable in the method. We can do that as follows:

changeValue(booleanValue){
     //Converting true to false or false to true
     this.isWorking = !booleanValue;
}

This will work as expected, but in some situations, we want to modularize a single variable to use multiple places, then this will not help.

How to Resolve this?

We can resolve this situation by simply using DOT(.) operator. Yes! we only need to use the dot for variables and models we are using in the application. So take a look at the changes we need to do.

Second Use-case

In Component, we will define a variable “data” of type any. Then add isWorking as part of it. In the method also we will take data as a parameter then take isWorking out of it to change its value.

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

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  
  data:any;

  constructor() {
	//Initialize value to false
    this.data.isWorking = false;
  }
  changeValue(booleanValue){
    //Converting true to false or false to true
	booleanValue.isWorking = !booleanValue.isWorking;
  }
}

In view, we will pass data as the parameter.

<div (click)="changeValue(data)">
      {{isWorking}} 
</div>

Conclusion

When working with model variables, it’s always preferred to keep them inside the main variable and using the model as a literal property. The dot(.) operator keeps the scope of the property intact as we discussed in our simple use-case above. We discussed on How to change model and variable values as a local variable in the method.

Leave a Reply

Your email address will not be published. Required fields are marked *