0

I am trying to detect changes to the properties of a model called 'invoice' so that a button can be enabled only when the values of this object are not the same as those of the initial model, 'initModel', created when the component was initialised.

So I need to be able to compare the two in the view like this:

<button mat-button (click)="saveChanges()" [disabled]="invoice !== initModel">Save Changes</button>

The 'invoice' model is initialised by giving it the value of another variable from a service in the constructor.

I've tried to figure out a way of setting an 'initModel' component variable, but this obviously binds with the 'invoice' model, so when the 'invoice' changes, the 'initModel' changes as well, and I can't set 'initModel' as a const that can be accessed in the view.

Component:

export class EditInvoiceComponent implements OnInit {

  invoice: Invoice;
  initModel;

  constructor(private invoicesService: InvoicesService) {
    this.invoice = this.invoicesService.selectedInvoice;
    this.initModel = this.invoice;
  }
nick.cook
  • 2,071
  • 4
  • 18
  • 36

2 Answers2

0

When you initialise initModel you are not creating a new object, you are simply passing a reference to the existing invoice object.

You can use the Spread Operator to create a clone (not a deep clone, mind you) of the initial object:

this.initModel = {...this.invoice};

If you require deep cloning you can use external libraries (like lodash), have a look at this detailed answer.

bugs
  • 14,631
  • 5
  • 48
  • 52
  • Thanks. This is kind of working to set the initModel as a copy of the initial model value, but when the component loads, even though both models are the same, a comparison with !== says that they aren't – nick.cook May 08 '18 at 09:27
  • I've logged both models to the console, however, and they are exact matches – nick.cook May 08 '18 at 09:27
  • Well, that's correct, because they are not the same object. I believe you have two options. The first (hacky) one is to do this: `JSON.stringify(this.initModel) === JSON.stringify(this.invoice)`, while the second (preferred) one is to use an external library (see [this answer](https://stackoverflow.com/questions/201183/how-to-determine-equality-for-two-javascript-objects)) – bugs May 08 '18 at 09:31
0

You can try below code:

$scope.isInvoiceValueChange=false;
$scope.$watch('invoice', function (newValue, oldValue, scope) {
                // Your logic here to validate value change with  initModel
            $scope.isInvoiceValueChange= true |false ; // based on your logic
},true); // use true if you need to watch nasted prop to trace 


<button mat-button (click)="saveChanges()" [disabled]="isInvoiceValueChange">Save Changes</button>