Angular 2x - Do not perform databinding for 2 equal objects

Asked

Viewed 67 times

-2

In my component I have 2 objects that use the same model, as below:

Component:

produtos: Produto[] = [];
produtosOriginal: Produto[] = [];

At a given time I make a copy of the values:

this.produtosOriginal = this.produtos;

In HTML, I do a for and link input to property:

HTML:

<ng-container *ngFor="let produto of produtos; let i = index;">
   ...

   <input class="form-control form-control-sm"
          type="number"
          min="1"
          step="1"
          (focusout)="validarItem(produto.id)" 
          (input)="validarItem(produto.id)"
          [ngClass]="{ 'is-invalid': produto.erroQtde }" 
          [(ngModel)]="produto.qtde" />
</ng-container>

When I make a change to the input the value is passed to the 2 objects, I have already checked if this value is being passed by another factor, more surely the problem is with the [(ngModel)]. How can I update only the object products.

Observing:

  1. I’m using Angular 8.
  2. I have tried using [(ngModel)]="products[i]. value" but no result.
  • 1

    The list produtos is a copy of produtosOriginal? if it is you will have to copy one to another using spread (...). That would be assimilation: produtos = {...produtosOriginal}; so the change in "products" does not reflect in "products".

  • I could not understand very well, because there are 2 different variables with the same type of object in the same component?

  • If you are populating produtos through the produtosOriginal as follows: this.produtos = this.produtosOriginal; you are not passing the values, you are passing the reference. Soon produtos points to produtosOriginal, and any change in produtos will change produtosOriginal. I hope you can understand...

  • Leonardo Getulio, I tried to do as you did, but for my logic it would be the opposite: this.productsOriginal = { ... this.products }; only that I can no longer access the methods for example: this.productsOriginal.length

  • Lucas Ayrosa, what would then be the correct way to popular a copy?

  • The way @Leonardogetulio really said it, only I believe the only mistake was the keys... It would be: this.produtosOriginal = [...this.produtos];. Test and see if it will solve your problem.

  • this.productsOriginal = [...this.products] = continues to reflect / this.productsOriginal = {...this.products} = lose methods of "productsOriginal"

  • Method or property? If it is method it is likely that you will lose even. If it is property/value it should not lose, this function is native, however it can scan the array and give . push() on each object but assimilate in a constant. Example: const copiaProduto = {...produtosOriginal[0]}; produtos.push(copiaProduto);. Forehead there, something calls here.

  • Do you mean that you keep modifying the two arrays? Because it should not happen. You can quickly test in the browser console by creating an example array, copying this one to another the way you were doing a = b and create a third with c = [...a], modifies the values of b and c and will see that only the change of b influence on a. Anyway, there’s another way to copy values: this.produtosOriginal = this.produtos.slice();. You can test it if you want.

  • If I use this.productsOriginal = { ...this.products } I lose the methods . find(), filter(), etc.. / If I use this.productsOriginal = [ ...this.products ] everything I change in products reflects in productsOriginal. About being working on the console really works, maybe it’s something with ngModel, I honestly don’t know.

Show 5 more comments

2 answers

0


You must clone the object so it doesn’t occur, follow the examples of how you might be doing it.

Method 01

this.produtosOriginal = [ ... this.produtos ];

Method 02

this.produtosOriginal = JSON.parse(JSON.stringify(this.produtos));
  • to copy arrays has to be with brackets

  • @Eduardovargas corrected, I did not notice that it was vector.

  • Method 02 worked, however, method 1 that looks more 'clean' continues to reflect the changes made in this.products.

  • @Alessandro I updated the answer, try with the new answer.

  • @Hiagosouza, had already tried after his change, but still persisted in reflecting, so I realized he creates a superficial copy, I chose to use a different approach that also worked: this.productsOriginal = this.productos.map(object => ({...object})); I suggest you include it in your reply. Thank you very much for your attention!

0

A quick way to clone a matrix..

clone(fn) {
    const arr = [...Array(1000000)];
    console.time('timer');
    fn(arr);
    console.timeEnd('timer');
}

Note: Of all the ways, the only way to deeply clone an array is by using

JSON.parse(JSON.stringify(arr)).

Browser other questions tagged

You are not signed in. Login or sign up in order to post.