Skip to content

refactor(signal-forms): unify how users access metadata added with define and metadata #62656

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 18, 2025

Conversation

mmalerba
Copy link
Contributor

Eliminates DataKey and FieldState.data as a separate user concept from metadata. DataKey is now StaticMetadataKey and is accessed via FieldState.metadata the same way as wth ReactiveMetadataKey. Note the there are still separate logic functions (define() and metadata()) for registering static and reactive metadata to a field. I'll try to unify the way they're created in a followup PR.

@ngbot ngbot bot added this to the Backlog milestone Jul 15, 2025
@mmalerba mmalerba requested review from leonsenft, kirjs and alxhub July 15, 2025 21:24
@mmalerba mmalerba marked this pull request as draft July 15, 2025 21:28
@mmalerba mmalerba marked this pull request as ready for review July 16, 2025 18:52
Co-authored-by: michael-small <33669563+michael-small@users.noreply.github.com>
@@ -74,5 +70,5 @@ export function defineResource<TValue, TData, TRequest, TPathKind extends PathKi
const pathNode = FieldPathNode.unwrapFieldPath(path);
pathNode.logic.addDataFactory(key, factory);

return key as DataKey<ResourceRef<TData | undefined>>;
return key as StaticMetadataKey<ResourceRef<TData | undefined>>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does the undefined come from / why is it necessary?

Both the opts.asKey and default value are just ResourceRef<TData>.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the schema doesn't set a particular static key for a particular field, but we try to read it: f().metadata(KEY) it returns undefined. This doesn't happen for reactive ones, because for those the key itself holds a default value to use in the case that the schema didn't define it at all for that field. Since the reactive ones represent reduced values, its basically the default case of reducing an empty list

* If the metadata is not defined for a given field, its value is undefined.
*/
export class StaticMetadataKey<TValue> extends KeyCtor<TValue> {
protected constructor() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any reason why these are protected while MetadataKey's constructor is private?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private prevents extending it, and we don't really want people to extend the base class. (We only know how to handle these two types of metadata)

@mmalerba mmalerba merged commit 63b4448 into angular:prototype/signal-forms Jul 18, 2025
11 of 18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

3 participants