Skip to content

two-way binding with a signal in @for-block throws a compilation error #54670

@lacolaco

Description

@lacolaco

Which @angular/* package(s) are the source of the bug?

compiler

Is this a regression?

Yes

Description

Two-way binding with a signal in @for-block throws a compilation error. Below is an example. In this example, nameModels is a Signal of the Signal array. Imagine a use case like FormArray for reactive forms. The template binds an input element to each element of nameModels. This example works perfectly when written with isolated bindings. However, replacing it with the "banana-in-a-box" syntax results in a compile error. (Stackblitz will not finish loading waiting for compilation)

Error: Illegal state: unsupported expression in two-way action binding.

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [CommonModule, FormsModule],
  template: `
    <h1>two-way binding with signals in for-block</h1>
    <div>
      @for(item of nameModels(); track $index){
        <!-- compile error -->
        <!-- <input type="text" [(ngModel)]="item" /> -->
        
        <!-- works -->
        <input
          type="text"
          [ngModel]="item()"
          (ngModelChange)="item.set($event)"
        />
      }
    </div>
  `,
})
export class App {
  nameModels: WritableSignal<WritableSignal<string>[]> = signal([
    signal('Angular'),
  ]);
}

This use case may not be common, but it is conceivable enough, and I believe the compiler should support this use case.
Since Signal is an object, not a primitive, temporary variables in iterations with for blocks should be pass-by-reference and modifiable. In fact, you can explicitly write item.set().

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/angular-mpactd?file=src%2Fmain.ts

Please provide the exception or error you saw

✘ [ERROR] Angular compilation emit failed. [plugin angular-compiler]

  Error: Illegal state: unsupported expression in two-way action binding.
      at wrapAssignmentAction (file:///Users/lacolaco/works/ng172signals/node_modules/@angular/compiler/fesm2022/compiler.mjs:7087:11)
      at convertAssignmentActionBinding (file:///Users/lacolaco/works/ng172signals/node_modules/@angular/compiler/fesm2022/compiler.mjs:7024:23)
      at prepareEventListenerParameters (file:///Users/lacolaco/works/ng172signals/node_modules/@angular/compiler/fesm2022/compiler.mjs:28169:9)
      at Object.paramsOrFn (file:///Users/lacolaco/works/ng172signals/node_modules/@angular/compiler/fesm2022/compiler.mjs:29795:20)
      at getInstructionStatements (file:///Users/lacolaco/works/ng172signals/node_modules/@angular/compiler/fesm2022/compiler.mjs:5195:84)
      at TemplateDefinitionBuilder.buildTemplateFunction (file:///Users/lacolaco/works/ng172signals/node_modules/@angular/compiler/fesm2022/compiler.mjs:28372:36)
      at file:///Users/lacolaco/works/ng172signals/node_modules/@angular/compiler/fesm2022/compiler.mjs:28908:50
      at file:///Users/lacolaco/works/ng172signals/node_modules/@angular/compiler/fesm2022/compiler.mjs:28350:60
      at Array.forEach (<anonymous>)
      at TemplateDefinitionBuilder.buildTemplateFunction (file:///Users/lacolaco/works/ng172signals/node_modules/@angular/compiler/fesm2022/compiler.mjs:28350:33)

Please provide the environment you discovered this bug in (run ng version)

Angular CLI: 17.2.2
Node: 20.11.0
Package Manager: npm 10.2.4
OS: darwin arm64

Angular: 17.2.3
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1702.2
@angular-devkit/build-angular   17.2.2
@angular-devkit/core            17.2.2
@angular-devkit/schematics      17.2.2
@angular/cli                    17.2.2
@schematics/angular             17.2.2
rxjs                            7.8.1
typescript                      5.3.3
zone.js                         0.14.4

Anything else?

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions