DonkeyBanana
DonkeyBanana

Reputation: 3556

Cannot assign to a reference or variable! (different situation than linked to)

This question is not solved by answers like this one despite a similar wording of the problem.

I'm using a custom component and the following work as supposed to. No errors, no warnings.

<app-setter [(setting)]="records[0]"></app-setter>
<app-setter [(setting)]="records[1]"></app-setter>
<app-setter [(setting)]="records[2]"></app-setter>

Naturally, I prefer to use a template generator like this.

<app-setter *ngFor="let record of records;"
            [(setting)]="record"></app-setter>

This produces the following error.

Cannot assign to a reference or variable!

Googling leads to a lot of hits on the same theme - there's a collision between a variable in the component and the ID of the generated tags. It's not the case here, as far I can see. I renamed the only field in my component to records and I don't even see any IDs being assigned to the generated tags.

What can be the cause of the issue and how can I diagnoze it further? I'm not sure how to learn the actual place where that occurs neither (it's compiler.js:xxxx, which tells me rather nothing).

edit

I've tried the following without success.

<ng-container *ngFor="let record of records;">
  <app-setter [(setting)]="record"></app-setter>
</ng-container>

However, I noticed that removing the bananas from the box-of-bananas makes the error vanish (of course with the result that the two-way binding is broken. This works:

<ng-container *ngFor="let record of records;">
  <app-setter [setting]="record"></app-setter>
</ng-container>

It tells me rather little. But it tells something, right?

The component code looks like this.

export class AssessmentComponent implements OnInit {
  constructor() { }
  records: Record[];
  ngOnInit() { this.records = [new Record("x", 3), new Record("y", 2)]; }
  onAddition(event: Record) { console.log(); }
}

Upvotes: 2

Views: 262

Answers (2)

thenolin
thenolin

Reputation: 1064

You need to set an index with the *ngFor loop like this.

 <app-setter *ngFor="let record of records; let i = index"
                [(setting)]="records[i]">
 </app-setter>

Like I was alluding to in my comment in the other solution, Nikhil's suggestion about using a ng-container is good practice. While you aren't doing it here, if you ever need an *ngIf & *ngFor on the same element, use the ng-container like described in the other answer and it will produce the desired effect.

Upvotes: 2

Nikhil
Nikhil

Reputation: 6641

EDIT: Credits to @thenolin for figuring it out. But from what OP has provided, I think we should use records[i] instead of record[i].

<app-setter *ngFor="let record of records; let i = index" [(setting)]="records[i]">
</app-setter>

Also, no need to use <ng-container>.

Original answer:

<ng-container *ngFor="let record of records;">
   <app-setter [(setting)]="record"></app-setter>
</ng-container>

ng-container is a grouping element that doesn't interfere with styles or layout.

You can replace <ng-container> in above snippet with <div> or any other element but it might affect your layout.

Upvotes: 2

Related Questions