2

In the html, I have to iterate over a WritableSignal object variableList(), but this html code will not run the loop unless the json string of the variableList() will show correctly in the same html.

html:

show JSON of variableList() : {{variableList() | json }}

@for (variable of variableList(); track [$index]; let i = $index) {   <!-- by this loop the UI look will generated by the variableList array -->
  loop test: {{i}}
}

And

variableList = signal<TVariable[]>([]);

The complete code is on Demo @ stackblitz

1 Answer 1

2

First we define the let i = $index, then we set the track by to the index we initialized in the previous step.

...
@for (variable of variableList(); let i = $index; track i) {
  loop test:
  ...
}
...

The main problem was, that we defined the signal to be of type array. But in the update method, we are performing Object Destructuring ({ ...someObj }) instead of array destructuring ([ ...someArr ]).

constructor() {
  this.variableList.update((v: TVariable[]) => {
    v.push(this.x(), this.y());
    return [...v];  // <- changed here!
  });
}

Full Code:

import { bootstrapApplication } from '@angular/platform-browser';
import { Component, signal } from '@angular/core';

import { FormsModule } from '@angular/forms';
import { JsonPipe } from '@angular/common';

@Component({
  selector: 'app-root',
  imports: [FormsModule, JsonPipe],
  template: `
      <h1> {{ title }}  </h1>
<hr>

show JSON of variableList() : {{variableList() | json }}
<hr>
here shuld be the loop:

@for (variable of variableList(); let i = $index; track i) {
  loop test:

  <table>
    <tr>
      <td>
        {{variable.name}} :
      </td>
      <td>
        <input
          [(ngModel)]='variable.index'>
      </td>
      <td>
        <input
          [(ngModel)]='variable.subindex'>
      </td>
      <td>
        <input
          [(ngModel)]='variable.value'>
      </td>
    </tr>
  </table>

 }
      
      
      `,
})
export class App {
  protected title = 'Angular Goes Functional';

  x = signal<TVariable>({
    name: 'X',
    value: 11,
    unit: 'N',
    index: '',
    subindex: '',
  });

  y = signal<TVariable>({
    name: 'Y',
    value: 33,
    unit: 'mm',
    index: '',
    subindex: '',
  });

  variableList = signal<TVariable[]>([]);

  constructor() {
    this.variableList.update((v: TVariable[]) => {
      v.push(this.x(), this.y());
      return [...v];
    });
  }
}

type TVariable = {
  name: string;
  index: string;
  subindex: string;
  value: number;
  unit: string;
  ID?: string;
};

bootstrapApplication(App);

Stackblitz Demo

Sign up to request clarification or add additional context in comments.

1 Comment

Let i = $index is not needed, you can use $index directly: track $index

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.