File

libs/acl/form-support/src/lib/support/form-walker.ts

Index

Properties

Properties

control
Type AbstractControl
controlPath
Type string
controlPathSegments
Type string[]
isFormArray
Type boolean
isFormGroup
Type boolean
import {
  AbstractControl,
  UntypedFormArray,
  UntypedFormControl,
  UntypedFormGroup
} from '@angular/forms';

export interface ControlItem {
  controlPath: string;
  controlPathSegments: string[];
  isFormGroup: boolean;
  isFormArray: boolean;
  control: AbstractControl;
}

/**
 * Check if it's a form group and use a TS type guard to let TS know
 * that it is indeed a FormGroup in the control flow
 */
export function checkIsFormGroup(control: AbstractControl): control is UntypedFormGroup {
  // duck test if this is a FormGroup
  return (
    control &&
    Object.prototype.hasOwnProperty.call(control, 'controls') &&
    control instanceof UntypedFormGroup
  );
}

export function checkIsFormArray(control: AbstractControl): control is UntypedFormArray {
  // duck test if this is a FormGroup
  return (
    control &&
    Object.prototype.hasOwnProperty.call(control, 'controls') &&
    control instanceof UntypedFormArray
  );
}

export function checkIsFormControl(control: AbstractControl): control is UntypedFormControl {
  return control && control instanceof UntypedFormControl;
}

function createControlItem({
  control,
  controlPathSegments,
  isFormGroup,
  isFormArray
}: {
  controlPathSegments: string[];
  isFormGroup: boolean;
  isFormArray: boolean;
  control: AbstractControl;
}): ControlItem {
  return {
    controlPath: controlPathSegments.join('.'),
    control,
    controlPathSegments,
    isFormGroup,
    isFormArray
  };
}

/**
 * walkFormGroup
 * @param {FormControl|FormGroup|FormArray} controlOrGroup
 * @param {object} options allows to set `includeFormGroups` parameter
 * @param {string} parentPath
 */
export function walkFormGroup(
  controlOrGroup: AbstractControl,
  { includeFormGroups = false } = {},
  parentPath: string[] = []
): ControlItem[] {
  const items: ControlItem[] = [];
  const formGroupItem: ControlItem = createControlItem({
    controlPathSegments: parentPath,
    isFormGroup: checkIsFormGroup(controlOrGroup),
    isFormArray: checkIsFormArray(controlOrGroup),
    control: controlOrGroup
  });

  if (checkIsFormControl(controlOrGroup)) {
    items.push(formGroupItem);
  } else if (checkIsFormArray(controlOrGroup) || checkIsFormGroup(controlOrGroup)) {
    const entries = Object.entries(controlOrGroup.controls);
    const isRootFormGroup = parentPath.length === 0;
    if (true === includeFormGroups && false === isRootFormGroup) {
      items.push(formGroupItem);
    }

    for (const [path, nestedControl] of entries) {
      const currentPath = [...parentPath, path];
      items.push(...walkFormGroup(nestedControl, { includeFormGroups }, currentPath));
    }
  }

  return items;
}

results matching ""

    No results matching ""