import { FormBuilder, FormControl } from '@angular/forms'; import { reduce } from 'lodash/fp'; /* * FORM UTILITIES * * Exports * ------- * buildFormGroup(metadata) - builds FormGroups from metdata, recursively if necessary * addMissingNames(metadata) - adds any missing 'name' properties to Fields and Groups using property's key, recursively * * Variable names * -------------- * metaF = metadata for Field * metaG = metadata for Group (possibly nested) * metaFoG = metadata for Field Or Group * */ const fb = new FormBuilder(); const addProp = (obj, key, val) => { obj[key] = val; return obj; }; // Helper function to distinguish group from field const isGroup = metaFoG => metaFoG.meta && !metaFoG._field; // Add names to both Fields and Groups if missing, using property's key const addNameIfMissing = (metaFoG, key) => metaFoG.name ? metaFoG : addProp(metaFoG, 'name', key); const addNameToSelfAndChildren = ( [key, metaFoG] ) => { metaFoG = addNameIfMissing(metaFoG, key); if (isGroup(metaFoG)) { metaFoG.meta = addMissingNames(metaFoG.meta); // Recursion } return [key, metaFoG]; }; const addMissingNames = metaG => Object.entries(metaG) .map(addNameToSelfAndChildren) .reduce((res, [key, val]) => { res[key] = val; return res; }, {}); // Build Form Control // TODO: Flesh out function to build validators const buildControlState = metaF => ({ value: metaF.value || '', disabled: metaF.isDisabled }); const buildValidators = metaF => ({ validators: null, asyncValidators: null, updateOn: 'blur' }); const buildFormControl = metaF => new FormControl(buildControlState(metaF) /*, buildValidators(metaF) */); // Build Form Group Member const buildFormGroupMember = metaFoG => isGroup(metaFoG) ? buildFormGroup(metaFoG.meta) : buildFormControl(metaFoG); // Build Form Group const buildFormGroupReducerIteree = (res, metaFoG) => Object.assign(res, { [metaFoG.name]: buildFormGroupMember(metaFoG) }); const buildFormGroup = metaG => fb.group(reduce(buildFormGroupReducerIteree, {}, metaG)); // --------------------------------------------------------------------------------------------------------------------- // Exports export { addMissingNames, buildFormGroup };