Describe the problem that you experienced
The "Value transformation" section of the Signal Forms custom controls guide teaches a manual pattern: a linkedSignal() for the display value plus a hand-written method that parses the user input back into the model on blur.
import {formatCurrency} from '@angular/common';
import {ChangeDetectionStrategy, Component, linkedSignal, model} from '@angular/core';
import {FormValueControl} from '@angular/forms/signals';
@Component({
selector: 'app-currency-input',
template: `
<input
type="text"
[value]="displayValue()"
(input)="displayValue.set($event.target.value)"
(blur)="updateModel()"
/>
`,
})
export class CurrencyInput implements FormValueControl<number> {
readonly value = model.required<number>();
readonly displayValue = linkedSignal(() => formatCurrency(this.value(), 'en', 'USD'));
updateModel() {
// [...]
}
}
Angular v22 ships transformedValue() in @angular/forms/signals, which is built for exactly this case: it returns a writable signal of the raw UI value kept in sync with the model through parse / format, exposes parseErrors, and — when used inside a field context — reports those parse errors to the nearest field automatically.
import {transformedValue} from '@angular/forms/signals';
@Component({
selector: 'number-input',
template: `<input [value]="rawValue()" (input)="rawValue.set($event.target.value)" />`,
})
export class NumberInput implements FormValueControl<number | null> {
readonly value = model.required<number | null>();
protected readonly rawValue = transformedValue(this.value, {
parse: (val) => {
// [...]
},
format: (val) => val?.toString() ?? '',
});
}
Because the guide never mentions it, readers hand-roll a weaker version of a feature the framework already provides.
Utility is discoverable only through the API reference — which a reader has no reason to open once the guide appears to have answered the question.
Enter the URL of the topic with the problem
https://angular.dev/guide/forms/signals/custom-controls#value-transformation
Describe what you were looking for in the documentation
The recommended "official" way to build a custom control with value transformation.
Describe what you want to experience that would fix the problem
If the official documentation states that transformedValue is the recommended approach (over a plain linkedSignal), I will align with it an existing feature of Taiga UI:
export abstract class TuiValueTransformer<From, To = unknown> {
public abstract toControlValue(componentValue: From): To;
public abstract fromControlValue(controlValue: To): From;
}
⬇️ (next major release) ⬇️
import type {ParseResult, TransformedValueOptions} from '@angular/forms/signals';
/**
* @deprecated implement `TransformedValueOptions` from `@angular/forms/signals` directly
*/
export abstract class TuiValueTransformer<From, To = unknown>
implements TransformedValueOptions<To, From>
{
public abstract parse: (rawValue: From) => ParseResult<To>;
public abstract format: (value: To) => From;
}
But I need a guarantee that this is really a stable API with no plans to remove it. Mentioning it in the official guide (https://angular.dev/guide/forms/signals/custom-controls#value-transformation) would be a good one.
Describe the problem that you experienced
The "Value transformation" section of the Signal Forms custom controls guide teaches a manual pattern: a
linkedSignal()for the display value plus a hand-written method that parses the user input back into the model on blur.Angular v22 ships transformedValue() in @angular/forms/signals, which is built for exactly this case: it returns a writable signal of the raw UI value kept in sync with the model through parse / format, exposes parseErrors, and — when used inside a field context — reports those parse errors to the nearest field automatically.
Because the guide never mentions it, readers hand-roll a weaker version of a feature the framework already provides.
Utility is discoverable only through the API reference — which a reader has no reason to open once the guide appears to have answered the question.
Enter the URL of the topic with the problem
https://angular.dev/guide/forms/signals/custom-controls#value-transformation
Describe what you were looking for in the documentation
The recommended "official" way to build a custom control with value transformation.
Describe what you want to experience that would fix the problem
If the official documentation states that
transformedValueis the recommended approach (over a plainlinkedSignal), I will align with it an existing feature of Taiga UI:⬇️ (next major release) ⬇️
But I need a guarantee that this is really a stable API with no plans to remove it. Mentioning it in the official guide (https://angular.dev/guide/forms/signals/custom-controls#value-transformation) would be a good one.