Skip to content

[signal forms] Documentation example for domain ↔ form model mapping creates a reactive loop #66647

@u-mikhalenka

Description

@u-mikhalenka

Describe the problem that you experienced

The documentation suggests using linkedSignal together with an effect to implement continuous saving when the domain model differs from the form model
(source).

However, this approach does not work as written because it introduces a reactive feedback loop:

  • linkedSignal depends on the domain model input
  • the form depends on the form model produced by linkedSignal
  • the auto-save effect depends on form.value, which is effectively the same form model signal

This results in an infinite cycle of:
domain → form → domain updates, even when no semantic changes occur.

Additionally, the sample code uses this.myForm.value(), but myForm is a function and must be invoked first to access the value signal (i.e. this.myForm().value()), which makes the example incorrect as written.

Working example with custom equality checks: Stackblitz
Commenting line 45 would cause infinite loop.

Current workarounds

From my understanding, the available workarounds are:

  • Implement custom equality checks to detect whether the domain model has actually changed before propagating updates.
  • Introduce a wrapper component that:
    • accepts the domain model
    • performs domain ↔ form mapping
    • passes only the form model to the actual form component

While first-class support for this mapping would be ideal, the Angular team has previously indicated that they do not plan to introduce additional APIs for this scenario (see #65194).

Request

Given the above, I suggest updating the documentation to include a correct, working example that avoids reactive loops and reflects the actual API usage. This would help prevent confusion and incorrect implementations based on the current guidance.

Enter the URL of the topic with the problem

https://angular.dev/guide/forms/signals/model-design#form-model-to-domain-model

Describe what you were looking for in the documentation

No response

Describe the actions that led you to experience the problem

No response

Describe what you want to experience that would fix the problem

No response

Add a screenshot if that helps illustrate the problem

No response

If this problem caused an exception or error, please paste it here


If the problem is browser-specific, please specify the device, OS, browser, and version


Provide any additional information here in as much as detail as you can


Metadata

Metadata

Assignees

Type

No type

Projects

Status

Todo

Relationships

None yet

Development

No branches or pull requests

Issue actions