MCPcopy Index your code
hub / github.com/angular/angular / get

Function get

packages/forms/signals/src/field/proxy.ts:17–73  ·  view source on GitHub ↗
(getTgt: () => FieldNode, p: string | symbol, receiver: {[key: string]: unknown})

Source from the content-addressed store, hash-verified

15 */
16export const FIELD_PROXY_HANDLER: ProxyHandler<() => FieldNode> = {
17 get(getTgt: () => FieldNode, p: string | symbol, receiver: {[key: string]: unknown}) {
18 const tgt = getTgt();
19
20 // First, check whether the requested property is a defined child node of this node.
21 const child = tgt.structure.getChild(p);
22 if (child !== undefined) {
23 // If so, return the child node's `FieldTree` proxy, allowing the developer to continue
24 // navigating the form structure.
25 return child.fieldTree;
26 }
27
28 // Otherwise, we need to consider whether the properties they're accessing are related to array
29 // iteration. We're specifically interested in `length`, but we only want to pass this through
30 // if the value is actually an array.
31 //
32 // We untrack the value here to avoid spurious reactive notifications. In reality, we've already
33 // incurred a dependency on the value via `tgt.getChild()` above.
34 const value = untracked(tgt.value);
35
36 if (isArray(value)) {
37 // Allow access to the length for field arrays, it should be the same as the length of the data.
38 if (p === 'length') {
39 return (tgt.value() as Array<unknown>).length;
40 }
41 // Allow access to the iterator. This allows the user to spread the field array into a
42 // standard array in order to call methods like `filter`, `map`, etc.
43 if (p === Symbol.iterator) {
44 return () => {
45 // When creating an iterator, we need to account for reactivity. The iterator itself will
46 // read things each time `.next()` is called, but that may happen outside of the context
47 // where the iterator was created (e.g. with `@for`, actual diffing happens outside the
48 // reactive context of the template).
49 //
50 // Instead, side-effectfully read the value here to ensure iterator creation is reactive.
51 tgt.value();
52 return Array.prototype[Symbol.iterator].apply(tgt.fieldTree);
53 };
54 }
55 // Note: We can consider supporting additional array methods if we want in the future,
56 // but they should be thoroughly tested. Just forwarding the method directly from the
57 // `Array` prototype results in broken behavior for some methods like `map`.
58 }
59
60 if (isObject(value)) {
61 // For object fields, allow iteration over their entries for convenience of use with `@for`.
62 if (p === Symbol.iterator) {
63 return function* () {
64 for (const key in receiver) {
65 yield [key, receiver[key]];
66 }
67 };
68 }
69 }
70
71 // Otherwise, this property doesn't exist.
72 return undefined;
73 },
74

Callers

nothing calls this directly

Calls 6

untrackedFunction · 0.90
isArrayFunction · 0.90
isObjectFunction · 0.90
getChildMethod · 0.65
valueMethod · 0.65
applyMethod · 0.65

Tested by

no test coverage detected