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

Function computeChildrenMap

packages/forms/signals/src/field/structure.ts:301–417  ·  view source on GitHub ↗
(
    value: unknown,
    prevData: ChildrenData | undefined,
    forceMaterialize: boolean,
  )

Source from the content-addressed store, hash-verified

299 }
300
301 private computeChildrenMap(
302 value: unknown,
303 prevData: ChildrenData | undefined,
304 forceMaterialize: boolean,
305 ): ChildrenData | undefined {
306 if (!isObject(value)) {
307 // Non-object values have no children. This short-circuit path makes `childrenMap` fast
308 // for primitive-valued fields.
309 return undefined;
310 }
311
312 // Determine if we actually need to materialize children right now.
313 // If not forced, and NO child has any logic rules, we can safely return `undefined`
314 // to keep instantiation lazy. However, if `prevData` is already defined, we MUST
315 // NOT return `undefined` or we will orphan the already instantiated children.
316 if (!forceMaterialize && prevData === undefined) {
317 // Check if any child of this field has logic rules. This check only needs to run once per
318 // structure since the presence of schema logic rules is static across value changes.
319 if (!(this._anyChildHasLogic ??= this.logic.anyChildHasLogic())) {
320 return undefined;
321 }
322 }
323
324 // Previous `ChildrenData` (immutable). This is also where we first initialize our map if
325 // needed.
326 prevData ??= {
327 byPropertyKey: new Map(),
328 };
329
330 // The next `ChildrenData` object to be returned. Initialized lazily when we know there's
331 // been a structural change to the model.
332 let materializedChildren: MutableChildrenData | undefined;
333
334 const parentIsArray = isArray(value);
335
336 // Remove fields that have disappeared since the last time this map was computed.
337 if (prevData !== undefined) {
338 if (parentIsArray) {
339 materializedChildren = maybeRemoveStaleArrayFields(prevData, value, this.identitySymbol);
340 } else {
341 materializedChildren = maybeRemoveStaleObjectFields(prevData, value);
342 }
343 }
344
345 // Now, go through the values and add any new ones.
346 for (const key of Object.keys(value)) {
347 let trackingKey: TrackingKey | undefined = undefined;
348 const childValue = value[key] as unknown;
349
350 // Fields explicitly set to `undefined` are treated as if they don't exist.
351 // This ensures that `{value: undefined}` and `{}` have the same behavior for their `value`
352 // field.
353 if (childValue === undefined) {
354 // The value might have _become_ `undefined`, so we need to delete it here.
355 if (prevData.byPropertyKey.has(key)) {
356 materializedChildren ??= {...(prevData as MutableChildrenData)};
357 materializedChildren.byPropertyKey.delete(key);
358 }

Callers

nothing calls this directly

Calls 10

isObjectFunction · 0.90
isArrayFunction · 0.90
anyChildHasLogicMethod · 0.65
keysMethod · 0.65
hasMethod · 0.65
setMethod · 0.65
getMethod · 0.65
deleteMethod · 0.45

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…