Which @angular/* package(s) are relevant/related to the feature request?
forms
Description
When submitting forms built with signal forms, one might want to exclude hidden fields from the submitted data. Currently there's no built-in way to get only visible field values.
Workarounds require manual mapping for known structures or have to rely on internal APIs. Especially, the transversal of a field tree of unknown structure is difficult when relying on the public API.
Proposed solution
Option 1: Expose internal helper to public API
Having access to FieldNode could significantly simplify the transversal of a nested field tree:
export function toVisibleValue<T>(formTree: FieldTree<T>): DeepPartial<T> {
const node = formTree as FieldNode;
// Clean access to node.structure.children()
}
Option 2: Provide high-level utilities
For example
export function toVisibleValue<T>(formTree: FieldTree<T>): DeepPartial<T>;
Alternatives considered
Manual Collection for Known Forms
const visibleData = {
name: this.form.name().hidden() ? undefined : this.form.name.value(),
};
Type-safe but not reusable. Requires rewriting for each form structure.
Manual Implementation with Internal APIs
type DeepPartial<T> = T extends (infer U)[]
? DeepPartial<U>[]
: T extends ReadonlyArray<infer U>
? ReadonlyArray<DeepPartial<U>>
: T extends object
? { [K in keyof T]?: DeepPartial<T[K]> }
: T;
function toVisableValue<T>(
form: FieldTree<T>,
): DeepPartial<T> | undefined {
const fieldState = form();
if (fieldState.hidden()) {
return undefined;
}
const childKeys = Object.keys(form).filter((key) => key !== 'value');
if (!childKeys.length) {
return fieldState.value() as DeepPartial<T>;
}
const fieldValue = fieldState.value();
if (Array.isArray(fieldValue)) {
const result: unknown[] = [];
for (const key of childKeys) {
const processed = processChildField(key, form);
if (processed !== undefined) {
result.push(processed);
}
}
return result as DeepPartial<T>;
}
const result: Record<string, unknown> = {};
for (const key of childKeys) {
const processed = processChildField(key, form);
if (processed !== undefined) {
result[key] = processed;
}
}
return result as DeepPartial<T>;
}
function processChildField<T>(
key: string,
fieldTree: FieldTree<T>,
): DeepPartial<unknown> | undefined {
const childField = (fieldTree as Record<string, unknown>)[key];
if (!childField) {
return undefined;
}
return toVisibleValue(childField as FieldTree<unknown>);
}
Works but fragile and may break with Angular updates.
Which @angular/* package(s) are relevant/related to the feature request?
forms
Description
When submitting forms built with signal forms, one might want to exclude hidden fields from the submitted data. Currently there's no built-in way to get only visible field values.
Workarounds require manual mapping for known structures or have to rely on internal APIs. Especially, the transversal of a field tree of unknown structure is difficult when relying on the public API.
Proposed solution
Option 1: Expose internal helper to public API
Having access to
FieldNodecould significantly simplify the transversal of a nested field tree:Option 2: Provide high-level utilities
For example
Alternatives considered
Manual Collection for Known Forms
Type-safe but not reusable. Requires rewriting for each form structure.
Manual Implementation with Internal APIs
Works but fragile and may break with Angular updates.