Skip to content

fix(upgrade): support model() signals in downgradeComponent#68760

Open
arturovt wants to merge 1 commit into
angular:mainfrom
arturovt:fix/upgrade-60599
Open

fix(upgrade): support model() signals in downgradeComponent#68760
arturovt wants to merge 1 commit into
angular:mainfrom
arturovt:fix/upgrade-60599

Conversation

@arturovt
Copy link
Copy Markdown
Contributor

model() signals are special because they combine a signal input with a writable output through an internal OutputEmitterRef. During upgrade, setupOutputs() subscribes to that emitter to keep Angular → AngularJS two-way binding working.

The issue was that updateInput() could overwrite the signal property directly when isSignal was false (which happens in JIT mode and when unsafelyOverwriteSignalInputs is enabled). Once that happened, the original OutputEmitterRef was lost, so the two-way binding stopped working.

The fix detects model() signals at runtime by checking for both [SIGNAL] and a writable .set() method, which distinguishes them from read-only input() signals. When those traits are present, updates are always applied through applyValueToInputSignal() instead of replacing the property directly, regardless of the unsafelyOverwriteSignalInputs setting.

Fixes #60599

`model()` signals are special because they combine a signal input with a writable output through an internal `OutputEmitterRef`. During upgrade, `setupOutputs()` subscribes to that emitter to keep Angular → AngularJS two-way binding working.

The issue was that `updateInput()` could overwrite the signal property directly when `isSignal` was `false` (which happens in JIT mode and when `unsafelyOverwriteSignalInputs` is enabled). Once that happened, the original `OutputEmitterRef` was lost, so the two-way binding stopped working.

The fix detects `model()` signals at runtime by checking for both `[SIGNAL]` and a writable `.set()` method, which distinguishes them from read-only `input()` signals. When those traits are present, updates are always applied through `applyValueToInputSignal()` instead of replacing the property directly, regardless of the `unsafelyOverwriteSignalInputs` setting.

Fixes angular#60599
@pullapprove pullapprove Bot requested a review from crisbeto May 16, 2026 22:11
@angular-robot angular-robot Bot added the area: upgrade Issues related to AngularJS → Angular upgrade APIs label May 16, 2026
@ngbot ngbot Bot added this to the Backlog milestone May 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: upgrade Issues related to AngularJS → Angular upgrade APIs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Signal model() support with downgradeComponent

1 participant