1

This is my demo code where i explain my goal in comments:

product.component.html

<div *ngFor="let item of items1">
  <div *ngFor="let item of items2">     
      <input type="text" value="{{data[getNumber()]}}"> //I want to get data[0] till data[6]
  </div>
</div>

product.component.ts

export class ProductComponent{

  itens1=["A","B","C","D"];
  itens2=["X","Y","Z"];
  data=[1,2,3,4,5,6,7];

  number=0;

  getNumber(){
    return this.number++;
  }

}

These are the errors i get:

enter image description here

I hope to have explained my problem well.

Elkin
  • 880
  • 2
  • 12
  • 26
  • Well, your question is a little bit confuse. What's data? A primitive array? Why do you need that function `getNumber()`? I don't know what do you want but you can try the following: `
    `.
    – developer033 Oct 29 '16 at 18:43
  • @developer033 Yes `data` is a primitive array. I have tryed your suggestion but i dont want to increment the index of `data` just when the second `ngFor` finishes. I want to increment it on each iteraction – Elkin Oct 29 '16 at 18:51
  • What do you mean by **"but i dont want to increment the index of data just when the second ngFor finishes"**? – developer033 Oct 29 '16 at 18:53
  • My bad. I mean i want to keep incrementing even when the second `ngFor` finishes. eg. `itens1=['A','B']; itens2=['X','Y']; data=[1,2,3,4];` i want `` to have `data[0]` untill `data[3]` – Elkin Oct 29 '16 at 18:59
  • See my answer. Also, you have to write `*ngFor`, not just `ngFor`, but I suspect that was just a typo. – Klas Mellbourn Oct 29 '16 at 19:39
  • @KlasMellbourn Yes, it's a typo. Thanks for the warning. – Elkin Oct 30 '16 at 11:15

1 Answers1

2

The problem is that every time getNumber() is called, it returns a different value than before.

Every time Angular2 evaluates what to set value to during change detection, it has changed, it never settles. Angular2 regards this as an error. See this answer for a more complete explanation.

The following code works the way you intend. Note that getNumber is now idempotent, it gives the same result for the same input. The input is gotten from the loops using the syntax let i = index.

@Component({
    selector: 'product',
    template: `
<div *ngFor="let item of items1; let i = index">
  <div *ngFor="let item of items2; let j = index">
      <input type="text" value="{{data[getNumber(i, j)]}}">
  </div>
</div>`
})
export class ProductComponent {
    items1 = ['A', 'B', 'C', 'D'];
    items2 = ['X', 'Y', 'Z'];
    data = [1, 2, 3, 4, 5, 6, 7];

    getNumber(i: number, j: number) {
        return i * this.items2.length + j;
    }
}
Community
  • 1
  • 1
Klas Mellbourn
  • 42,571
  • 24
  • 140
  • 158
  • One upvote for the answer but could it be more dynamic? I mean if `itens1.length` is 4 and `itens2.length` is 3 and `data` has more values, the `getNumber()` function will not return ordered indices. Check my edits on the question for details. – Elkin Oct 30 '16 at 11:12
  • I've updated with larger arrays and a more generic `getNumber`. Note that the as the example stands it works but it runs out of `data` values to display, since you would need `itens1.length * itens2.length` values in `data`. – Klas Mellbourn Oct 30 '16 at 13:21