/** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ var __extends = (this && this.__extends) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; import { fromPromise } from 'rxjs/observable/fromPromise'; import { composeAsyncValidators, composeValidators } from './directives/shared'; import { EventEmitter } from './facade/async'; import { isPromise } from './private_import_core'; /** * Indicates that a FormControl is valid, i.e. that no errors exist in the input value. */ export var /** @type {?} */ VALID = 'VALID'; /** * Indicates that a FormControl is invalid, i.e. that an error exists in the input value. */ export var /** @type {?} */ INVALID = 'INVALID'; /** * Indicates that a FormControl is pending, i.e. that async validation is occurring and * errors are not yet available for the input value. */ export var /** @type {?} */ PENDING = 'PENDING'; /** * Indicates that a FormControl is disabled, i.e. that the control is exempt from ancestor * calculations of validity or value. */ export var /** @type {?} */ DISABLED = 'DISABLED'; /** * @param {?} control * @param {?} path * @param {?} delimiter * @return {?} */ function _find(control, path, delimiter) { if (path == null) return null; if (!(path instanceof Array)) { path = ((path)).split(delimiter); } if (path instanceof Array && (path.length === 0)) return null; return ((path)).reduce(function (v, name) { if (v instanceof FormGroup) { return v.controls[name] || null; } if (v instanceof FormArray) { return v.at(/** @type {?} */ (name)) || null; } return null; }, control); } /** * @param {?} r * @return {?} */ function toObservable(r) { return isPromise(r) ? fromPromise(r) : r; } /** * @param {?} validator * @return {?} */ function coerceToValidator(validator) { return Array.isArray(validator) ? composeValidators(validator) : validator; } /** * @param {?} asyncValidator * @return {?} */ function coerceToAsyncValidator(asyncValidator) { return Array.isArray(asyncValidator) ? composeAsyncValidators(asyncValidator) : asyncValidator; } /** * \@whatItDoes This is the base class for {\@link FormControl}, {\@link FormGroup}, and * {\@link FormArray}. * * It provides some of the shared behavior that all controls and groups of controls have, like * running validators, calculating status, and resetting state. It also defines the properties * that are shared between all sub-classes, like `value`, `valid`, and `dirty`. It shouldn't be * instantiated directly. * * \@stable * @abstract */ export var AbstractControl = (function () { /** * @param {?} validator * @param {?} asyncValidator */ function AbstractControl(validator, asyncValidator) { this.validator = validator; this.asyncValidator = asyncValidator; /** @internal */ this._onCollectionChange = function () { }; this._pristine = true; this._touched = false; /** @internal */ this._onDisabledChange = []; } Object.defineProperty(AbstractControl.prototype, "value", { /** * The value of the control. * @return {?} */ get: function () { return this._value; }, enumerable: true, configurable: true }); Object.defineProperty(AbstractControl.prototype, "parent", { /** * The parent control. * @return {?} */ get: function () { return this._parent; }, enumerable: true, configurable: true }); Object.defineProperty(AbstractControl.prototype, "status", { /** * The validation status of the control. There are four possible * validation statuses: * * * **VALID**: control has passed all validation checks * * **INVALID**: control has failed at least one validation check * * **PENDING**: control is in the midst of conducting a validation check * * **DISABLED**: control is exempt from validation checks * * These statuses are mutually exclusive, so a control cannot be * both valid AND invalid or invalid AND disabled. * @return {?} */ get: function () { return this._status; }, enumerable: true, configurable: true }); Object.defineProperty(AbstractControl.prototype, "valid", { /** * A control is `valid` when its `status === VALID`. * * In order to have this status, the control must have passed all its * validation checks. * @return {?} */ get: function () { return this._status === VALID; }, enumerable: true, configurable: true }); Object.defineProperty(AbstractControl.prototype, "invalid", { /** * A control is `invalid` when its `status === INVALID`. * * In order to have this status, the control must have failed * at least one of its validation checks. * @return {?} */ get: function () { return this._status === INVALID; }, enumerable: true, configurable: true }); Object.defineProperty(AbstractControl.prototype, "pending", { /** * A control is `pending` when its `status === PENDING`. * * In order to have this status, the control must be in the * middle of conducting a validation check. * @return {?} */ get: function () { return this._status == PENDING; }, enumerable: true, configurable: true }); Object.defineProperty(AbstractControl.prototype, "disabled", { /** * A control is `disabled` when its `status === DISABLED`. * * Disabled controls are exempt from validation checks and * are not included in the aggregate value of their ancestor * controls. * @return {?} */ get: function () { return this._status === DISABLED; }, enumerable: true, configurable: true }); Object.defineProperty(AbstractControl.prototype, "enabled", { /** * A control is `enabled` as long as its `status !== DISABLED`. * * In other words, it has a status of `VALID`, `INVALID`, or * `PENDING`. * @return {?} */ get: function () { return this._status !== DISABLED; }, enumerable: true, configurable: true }); Object.defineProperty(AbstractControl.prototype, "errors", { /** * Returns any errors generated by failing validation. If there * are no errors, it will return null. * @return {?} */ get: function () { return this._errors; }, enumerable: true, configurable: true }); Object.defineProperty(AbstractControl.prototype, "pristine", { /** * A control is `pristine` if the user has not yet changed * the value in the UI. * * Note that programmatic changes to a control's value will * *not* mark it dirty. * @return {?} */ get: function () { return this._pristine; }, enumerable: true, configurable: true }); Object.defineProperty(AbstractControl.prototype, "dirty", { /** * A control is `dirty` if the user has changed the value * in the UI. * * Note that programmatic changes to a control's value will * *not* mark it dirty. * @return {?} */ get: function () { return !this.pristine; }, enumerable: true, configurable: true }); Object.defineProperty(AbstractControl.prototype, "touched", { /** * A control is marked `touched` once the user has triggered * a `blur` event on it. * @return {?} */ get: function () { return this._touched; }, enumerable: true, configurable: true }); Object.defineProperty(AbstractControl.prototype, "untouched", { /** * A control is `untouched` if the user has not yet triggered * a `blur` event on it. * @return {?} */ get: function () { return !this._touched; }, enumerable: true, configurable: true }); Object.defineProperty(AbstractControl.prototype, "valueChanges", { /** * Emits an event every time the value of the control changes, in * the UI or programmatically. * @return {?} */ get: function () { return this._valueChanges; }, enumerable: true, configurable: true }); Object.defineProperty(AbstractControl.prototype, "statusChanges", { /** * Emits an event every time the validation status of the control * is re-calculated. * @return {?} */ get: function () { return this._statusChanges; }, enumerable: true, configurable: true }); /** * Sets the synchronous validators that are active on this control. Calling * this will overwrite any existing sync validators. * @param {?} newValidator * @return {?} */ AbstractControl.prototype.setValidators = function (newValidator) { this.validator = coerceToValidator(newValidator); }; /** * Sets the async validators that are active on this control. Calling this * will overwrite any existing async validators. * @param {?} newValidator * @return {?} */ AbstractControl.prototype.setAsyncValidators = function (newValidator) { this.asyncValidator = coerceToAsyncValidator(newValidator); }; /** * Empties out the sync validator list. * @return {?} */ AbstractControl.prototype.clearValidators = function () { this.validator = null; }; /** * Empties out the async validator list. * @return {?} */ AbstractControl.prototype.clearAsyncValidators = function () { this.asyncValidator = null; }; /** * Marks the control as `touched`. * * This will also mark all direct ancestors as `touched` to maintain * the model. * @param {?=} __0 * @return {?} */ AbstractControl.prototype.markAsTouched = function (_a) { var onlySelf = (_a === void 0 ? {} : _a).onlySelf; this._touched = true; if (this._parent && !onlySelf) { this._parent.markAsTouched({ onlySelf: onlySelf }); } }; /** * Marks the control as `untouched`. * * If the control has any children, it will also mark all children as `untouched` * to maintain the model, and re-calculate the `touched` status of all parent * controls. * @param {?=} __0 * @return {?} */ AbstractControl.prototype.markAsUntouched = function (_a) { var onlySelf = (_a === void 0 ? {} : _a).onlySelf; this._touched = false; this._forEachChild(function (control) { control.markAsUntouched({ onlySelf: true }); }); if (this._parent && !onlySelf) { this._parent._updateTouched({ onlySelf: onlySelf }); } }; /** * Marks the control as `dirty`. * * This will also mark all direct ancestors as `dirty` to maintain * the model. * @param {?=} __0 * @return {?} */ AbstractControl.prototype.markAsDirty = function (_a) { var onlySelf = (_a === void 0 ? {} : _a).onlySelf; this._pristine = false; if (this._parent && !onlySelf) { this._parent.markAsDirty({ onlySelf: onlySelf }); } }; /** * Marks the control as `pristine`. * * If the control has any children, it will also mark all children as `pristine` * to maintain the model, and re-calculate the `pristine` status of all parent * controls. * @param {?=} __0 * @return {?} */ AbstractControl.prototype.markAsPristine = function (_a) { var onlySelf = (_a === void 0 ? {} : _a).onlySelf; this._pristine = true; this._forEachChild(function (control) { control.markAsPristine({ onlySelf: true }); }); if (this._parent && !onlySelf) { this._parent._updatePristine({ onlySelf: onlySelf }); } }; /** * Marks the control as `pending`. * @param {?=} __0 * @return {?} */ AbstractControl.prototype.markAsPending = function (_a) { var onlySelf = (_a === void 0 ? {} : _a).onlySelf; this._status = PENDING; if (this._parent && !onlySelf) { this._parent.markAsPending({ onlySelf: onlySelf }); } }; /** * Disables the control. This means the control will be exempt from validation checks and * excluded from the aggregate value of any parent. Its status is `DISABLED`. * * If the control has children, all children will be disabled to maintain the model. * @param {?=} __0 * @return {?} */ AbstractControl.prototype.disable = function (_a) { var _b = _a === void 0 ? {} : _a, onlySelf = _b.onlySelf, emitEvent = _b.emitEvent; this._status = DISABLED; this._errors = null; this._forEachChild(function (control) { control.disable({ onlySelf: true }); }); this._updateValue(); if (emitEvent !== false) { this._valueChanges.emit(this._value); this._statusChanges.emit(this._status); } this._updateAncestors(onlySelf); this._onDisabledChange.forEach(function (changeFn) { return changeFn(true); }); }; /** * Enables the control. This means the control will be included in validation checks and * the aggregate value of its parent. Its status is re-calculated based on its value and * its validators. * * If the control has children, all children will be enabled. * @param {?=} __0 * @return {?} */ AbstractControl.prototype.enable = function (_a) { var _b = _a === void 0 ? {} : _a, onlySelf = _b.onlySelf, emitEvent = _b.emitEvent; this._status = VALID; this._forEachChild(function (control) { control.enable({ onlySelf: true }); }); this.updateValueAndValidity({ onlySelf: true, emitEvent: emitEvent }); this._updateAncestors(onlySelf); this._onDisabledChange.forEach(function (changeFn) { return changeFn(false); }); }; /** * @param {?} onlySelf * @return {?} */ AbstractControl.prototype._updateAncestors = function (onlySelf) { if (this._parent && !onlySelf) { this._parent.updateValueAndValidity(); this._parent._updatePristine(); this._parent._updateTouched(); } }; /** * @param {?} parent * @return {?} */ AbstractControl.prototype.setParent = function (parent) { this._parent = parent; }; /** * Sets the value of the control. Abstract method (implemented in sub-classes). * @abstract * @param {?} value * @param {?=} options * @return {?} */ AbstractControl.prototype.setValue = function (value, options) { }; /** * Patches the value of the control. Abstract method (implemented in sub-classes). * @abstract * @param {?} value * @param {?=} options * @return {?} */ AbstractControl.prototype.patchValue = function (value, options) { }; /** * Resets the control. Abstract method (implemented in sub-classes). * @abstract * @param {?=} value * @param {?=} options * @return {?} */ AbstractControl.prototype.reset = function (value, options) { }; /** * Re-calculates the value and validation status of the control. * * By default, it will also update the value and validity of its ancestors. * @param {?=} __0 * @return {?} */ AbstractControl.prototype.updateValueAndValidity = function (_a) { var _b = _a === void 0 ? {} : _a, onlySelf = _b.onlySelf, emitEvent = _b.emitEvent; this._setInitialStatus(); this._updateValue(); if (this.enabled) { this._errors = this._runValidator(); this._status = this._calculateStatus(); if (this._status === VALID || this._status === PENDING) { this._runAsyncValidator(emitEvent); } } if (emitEvent !== false) { this._valueChanges.emit(this._value); this._statusChanges.emit(this._status); } if (this._parent && !onlySelf) { this._parent.updateValueAndValidity({ onlySelf: onlySelf, emitEvent: emitEvent }); } }; /** * \@internal * @param {?=} __0 * @return {?} */ AbstractControl.prototype._updateTreeValidity = function (_a) { var emitEvent = (_a === void 0 ? { emitEvent: true } : _a).emitEvent; this._forEachChild(function (ctrl) { return ctrl._updateTreeValidity({ emitEvent: emitEvent }); }); this.updateValueAndValidity({ onlySelf: true, emitEvent: emitEvent }); }; /** * @return {?} */ AbstractControl.prototype._setInitialStatus = function () { this._status = this._allControlsDisabled() ? DISABLED : VALID; }; /** * @return {?} */ AbstractControl.prototype._runValidator = function () { return this.validator ? this.validator(this) : null; }; /** * @param {?} emitEvent * @return {?} */ AbstractControl.prototype._runAsyncValidator = function (emitEvent) { var _this = this; if (this.asyncValidator) { this._status = PENDING; this._cancelExistingSubscription(); var /** @type {?} */ obs = toObservable(this.asyncValidator(this)); this._asyncValidationSubscription = obs.subscribe({ next: function (res) { return _this.setErrors(res, { emitEvent: emitEvent }); } }); } }; /** * @return {?} */ AbstractControl.prototype._cancelExistingSubscription = function () { if (this._asyncValidationSubscription) { this._asyncValidationSubscription.unsubscribe(); } }; /** * Sets errors on a form control. * * This is used when validations are run manually by the user, rather than automatically. * * Calling `setErrors` will also update the validity of the parent control. * * ### Example * * ``` * const login = new FormControl("someLogin"); * login.setErrors({ * "notUnique": true * }); * * expect(login.valid).toEqual(false); * expect(login.errors).toEqual({"notUnique": true}); * * login.setValue("someOtherLogin"); * * expect(login.valid).toEqual(true); * ``` * @param {?} errors * @param {?=} __1 * @return {?} */ AbstractControl.prototype.setErrors = function (errors, _a) { var emitEvent = (_a === void 0 ? {} : _a).emitEvent; this._errors = errors; this._updateControlsErrors(emitEvent !== false); }; /** * Retrieves a child control given the control's name or path. * * Paths can be passed in as an array or a string delimited by a dot. * * To get a control nested within a `person` sub-group: * * * `this.form.get('person.name');` * * -OR- * * * `this.form.get(['person', 'name']);` * @param {?} path * @return {?} */ AbstractControl.prototype.get = function (path) { return _find(this, path, '.'); }; /** * Returns true if the control with the given path has the error specified. Otherwise * returns null or undefined. * * If no path is given, it checks for the error on the present control. * @param {?} errorCode * @param {?=} path * @return {?} */ AbstractControl.prototype.getError = function (errorCode, path) { if (path === void 0) { path = null; } var /** @type {?} */ control = path ? this.get(path) : this; return control && control._errors ? control._errors[errorCode] : null; }; /** * Returns true if the control with the given path has the error specified. Otherwise * returns false. * * If no path is given, it checks for the error on the present control. * @param {?} errorCode * @param {?=} path * @return {?} */ AbstractControl.prototype.hasError = function (errorCode, path) { if (path === void 0) { path = null; } return !!this.getError(errorCode, path); }; Object.defineProperty(AbstractControl.prototype, "root", { /** * Retrieves the top-level ancestor of this control. * @return {?} */ get: function () { var /** @type {?} */ x = this; while (x._parent) { x = x._parent; } return x; }, enumerable: true, configurable: true }); /** * \@internal * @param {?} emitEvent * @return {?} */ AbstractControl.prototype._updateControlsErrors = function (emitEvent) { this._status = this._calculateStatus(); if (emitEvent) { this._statusChanges.emit(this._status); } if (this._parent) { this._parent._updateControlsErrors(emitEvent); } }; /** * \@internal * @return {?} */ AbstractControl.prototype._initObservables = function () { this._valueChanges = new EventEmitter(); this._statusChanges = new EventEmitter(); }; /** * @return {?} */ AbstractControl.prototype._calculateStatus = function () { if (this._allControlsDisabled()) return DISABLED; if (this._errors) return INVALID; if (this._anyControlsHaveStatus(PENDING)) return PENDING; if (this._anyControlsHaveStatus(INVALID)) return INVALID; return VALID; }; /** * \@internal * @abstract * @return {?} */ AbstractControl.prototype._updateValue = function () { }; /** * \@internal * @abstract * @param {?} cb * @return {?} */ AbstractControl.prototype._forEachChild = function (cb) { }; /** * \@internal * @abstract * @param {?} condition * @return {?} */ AbstractControl.prototype._anyControls = function (condition) { }; /** * \@internal * @abstract * @return {?} */ AbstractControl.prototype._allControlsDisabled = function () { }; /** * \@internal * @param {?} status * @return {?} */ AbstractControl.prototype._anyControlsHaveStatus = function (status) { return this._anyControls(function (control) { return control.status === status; }); }; /** * \@internal * @return {?} */ AbstractControl.prototype._anyControlsDirty = function () { return this._anyControls(function (control) { return control.dirty; }); }; /** * \@internal * @return {?} */ AbstractControl.prototype._anyControlsTouched = function () { return this._anyControls(function (control) { return control.touched; }); }; /** * \@internal * @param {?=} __0 * @return {?} */ AbstractControl.prototype._updatePristine = function (_a) { var onlySelf = (_a === void 0 ? {} : _a).onlySelf; this._pristine = !this._anyControlsDirty(); if (this._parent && !onlySelf) { this._parent._updatePristine({ onlySelf: onlySelf }); } }; /** * \@internal * @param {?=} __0 * @return {?} */ AbstractControl.prototype._updateTouched = function (_a) { var onlySelf = (_a === void 0 ? {} : _a).onlySelf; this._touched = this._anyControlsTouched(); if (this._parent && !onlySelf) { this._parent._updateTouched({ onlySelf: onlySelf }); } }; /** * \@internal * @param {?} formState * @return {?} */ AbstractControl.prototype._isBoxedValue = function (formState) { return typeof formState === 'object' && formState !== null && Object.keys(formState).length === 2 && 'value' in formState && 'disabled' in formState; }; /** * \@internal * @param {?} fn * @return {?} */ AbstractControl.prototype._registerOnCollectionChange = function (fn) { this._onCollectionChange = fn; }; return AbstractControl; }()); function AbstractControl_tsickle_Closure_declarations() { /** * \@internal * @type {?} */ AbstractControl.prototype._value; /** * \@internal * @type {?} */ AbstractControl.prototype._onCollectionChange; /** @type {?} */ AbstractControl.prototype._valueChanges; /** @type {?} */ AbstractControl.prototype._statusChanges; /** @type {?} */ AbstractControl.prototype._status; /** @type {?} */ AbstractControl.prototype._errors; /** @type {?} */ AbstractControl.prototype._pristine; /** @type {?} */ AbstractControl.prototype._touched; /** @type {?} */ AbstractControl.prototype._parent; /** @type {?} */ AbstractControl.prototype._asyncValidationSubscription; /** * \@internal * @type {?} */ AbstractControl.prototype._onDisabledChange; /** @type {?} */ AbstractControl.prototype.validator; /** @type {?} */ AbstractControl.prototype.asyncValidator; } /** * \@whatItDoes Tracks the value and validation status of an individual form control. * * It is one of the three fundamental building blocks of Angular forms, along with * {\@link FormGroup} and {\@link FormArray}. * * \@howToUse * * When instantiating a {\@link FormControl}, you can pass in an initial value as the * first argument. Example: * * ```ts * const ctrl = new FormControl('some value'); * console.log(ctrl.value); // 'some value' * ``` * * You can also initialize the control with a form state object on instantiation, * which includes both the value and whether or not the control is disabled. * You can't use the value key without the disabled key; both are required * to use this way of initialization. * * ```ts * const ctrl = new FormControl({value: 'n/a', disabled: true}); * console.log(ctrl.value); // 'n/a' * console.log(ctrl.status); // 'DISABLED' * ``` * * To include a sync validator (or an array of sync validators) with the control, * pass it in as the second argument. Async validators are also supported, but * have to be passed in separately as the third arg. * * ```ts * const ctrl = new FormControl('', Validators.required); * console.log(ctrl.value); // '' * console.log(ctrl.status); // 'INVALID' * ``` * * See its superclass, {\@link AbstractControl}, for more properties and methods. * * * **npm package**: `\@angular/forms` * * \@stable */ export var FormControl = (function (_super) { __extends(FormControl, _super); /** * @param {?=} formState * @param {?=} validator * @param {?=} asyncValidator */ function FormControl(formState, validator, asyncValidator) { if (formState === void 0) { formState = null; } if (validator === void 0) { validator = null; } if (asyncValidator === void 0) { asyncValidator = null; } _super.call(this, coerceToValidator(validator), coerceToAsyncValidator(asyncValidator)); /** @internal */ this._onChange = []; this._applyFormState(formState); this.updateValueAndValidity({ onlySelf: true, emitEvent: false }); this._initObservables(); } /** * Set the value of the form control to `value`. * * If `onlySelf` is `true`, this change will only affect the validation of this `FormControl` * and not its parent component. This defaults to false. * * If `emitEvent` is `true`, this * change will cause a `valueChanges` event on the `FormControl` to be emitted. This defaults * to true (as it falls through to `updateValueAndValidity`). * * If `emitModelToViewChange` is `true`, the view will be notified about the new value * via an `onChange` event. This is the default behavior if `emitModelToViewChange` is not * specified. * * If `emitViewToModelChange` is `true`, an ngModelChange event will be fired to update the * model. This is the default behavior if `emitViewToModelChange` is not specified. * @param {?} value * @param {?=} __1 * @return {?} */ FormControl.prototype.setValue = function (value, _a) { var _this = this; var _b = _a === void 0 ? {} : _a, onlySelf = _b.onlySelf, emitEvent = _b.emitEvent, emitModelToViewChange = _b.emitModelToViewChange, emitViewToModelChange = _b.emitViewToModelChange; this._value = value; if (this._onChange.length && emitModelToViewChange !== false) { this._onChange.forEach(function (changeFn) { return changeFn(_this._value, emitViewToModelChange !== false); }); } this.updateValueAndValidity({ onlySelf: onlySelf, emitEvent: emitEvent }); }; /** * Patches the value of a control. * * This function is functionally the same as {\@link FormControl.setValue} at this level. * It exists for symmetry with {\@link FormGroup.patchValue} on `FormGroups` and `FormArrays`, * where it does behave differently. * @param {?} value * @param {?=} options * @return {?} */ FormControl.prototype.patchValue = function (value, options) { if (options === void 0) { options = {}; } this.setValue(value, options); }; /** * Resets the form control. This means by default: * * * it is marked as `pristine` * * it is marked as `untouched` * * value is set to null * * You can also reset to a specific form state by passing through a standalone * value or a form state object that contains both a value and a disabled state * (these are the only two properties that cannot be calculated). * * Ex: * * ```ts * this.control.reset('Nancy'); * * console.log(this.control.value); // 'Nancy' * ``` * * OR * * ``` * this.control.reset({value: 'Nancy', disabled: true}); * * console.log(this.control.value); // 'Nancy' * console.log(this.control.status); // 'DISABLED' * ``` * @param {?=} formState * @param {?=} __1 * @return {?} */ FormControl.prototype.reset = function (formState, _a) { if (formState === void 0) { formState = null; } var _b = _a === void 0 ? {} : _a, onlySelf = _b.onlySelf, emitEvent = _b.emitEvent; this._applyFormState(formState); this.markAsPristine({ onlySelf: onlySelf }); this.markAsUntouched({ onlySelf: onlySelf }); this.setValue(this._value, { onlySelf: onlySelf, emitEvent: emitEvent }); }; /** * \@internal * @return {?} */ FormControl.prototype._updateValue = function () { }; /** * \@internal * @param {?} condition * @return {?} */ FormControl.prototype._anyControls = function (condition) { return false; }; /** * \@internal * @return {?} */ FormControl.prototype._allControlsDisabled = function () { return this.disabled; }; /** * Register a listener for change events. * @param {?} fn * @return {?} */ FormControl.prototype.registerOnChange = function (fn) { this._onChange.push(fn); }; /** * \@internal * @return {?} */ FormControl.prototype._clearChangeFns = function () { this._onChange = []; this._onDisabledChange = []; this._onCollectionChange = function () { }; }; /** * Register a listener for disabled events. * @param {?} fn * @return {?} */ FormControl.prototype.registerOnDisabledChange = function (fn) { this._onDisabledChange.push(fn); }; /** * \@internal * @param {?} cb * @return {?} */ FormControl.prototype._forEachChild = function (cb) { }; /** * @param {?} formState * @return {?} */ FormControl.prototype._applyFormState = function (formState) { if (this._isBoxedValue(formState)) { this._value = formState.value; formState.disabled ? this.disable({ onlySelf: true, emitEvent: false }) : this.enable({ onlySelf: true, emitEvent: false }); } else { this._value = formState; } }; return FormControl; }(AbstractControl)); function FormControl_tsickle_Closure_declarations() { /** * \@internal * @type {?} */ FormControl.prototype._onChange; } /** * \@whatItDoes Tracks the value and validity state of a group of {\@link FormControl} * instances. * * A `FormGroup` aggregates the values of each child {\@link FormControl} into one object, * with each control name as the key. It calculates its status by reducing the statuses * of its children. For example, if one of the controls in a group is invalid, the entire * group becomes invalid. * * `FormGroup` is one of the three fundamental building blocks used to define forms in Angular, * along with {\@link FormControl} and {\@link FormArray}. * * \@howToUse * * When instantiating a {\@link FormGroup}, pass in a collection of child controls as the first * argument. The key for each child will be the name under which it is registered. * * ### Example * * ``` * const form = new FormGroup({ * first: new FormControl('Nancy', Validators.minLength(2)), * last: new FormControl('Drew'), * }); * * console.log(form.value); // {first: 'Nancy', last; 'Drew'} * console.log(form.status); // 'VALID' * ``` * * You can also include group-level validators as the second arg, or group-level async * validators as the third arg. These come in handy when you want to perform validation * that considers the value of more than one child control. * * ### Example * * ``` * const form = new FormGroup({ * password: new FormControl('', Validators.minLength(2)), * passwordConfirm: new FormControl('', Validators.minLength(2)), * }, passwordMatchValidator); * * * function passwordMatchValidator(g: FormGroup) { * return g.get('password').value === g.get('passwordConfirm').value * ? null : {'mismatch': true}; * } * ``` * * * **npm package**: `\@angular/forms` * * \@stable */ export var FormGroup = (function (_super) { __extends(FormGroup, _super); /** * @param {?} controls * @param {?=} validator * @param {?=} asyncValidator */ function FormGroup(controls, validator, asyncValidator) { if (validator === void 0) { validator = null; } if (asyncValidator === void 0) { asyncValidator = null; } _super.call(this, validator, asyncValidator); this.controls = controls; this._initObservables(); this._setUpControls(); this.updateValueAndValidity({ onlySelf: true, emitEvent: false }); } /** * Registers a control with the group's list of controls. * * This method does not update value or validity of the control, so for * most cases you'll want to use {\@link FormGroup.addControl} instead. * @param {?} name * @param {?} control * @return {?} */ FormGroup.prototype.registerControl = function (name, control) { if (this.controls[name]) return this.controls[name]; this.controls[name] = control; control.setParent(this); control._registerOnCollectionChange(this._onCollectionChange); return control; }; /** * Add a control to this group. * @param {?} name * @param {?} control * @return {?} */ FormGroup.prototype.addControl = function (name, control) { this.registerControl(name, control); this.updateValueAndValidity(); this._onCollectionChange(); }; /** * Remove a control from this group. * @param {?} name * @return {?} */ FormGroup.prototype.removeControl = function (name) { if (this.controls[name]) this.controls[name]._registerOnCollectionChange(function () { }); delete (this.controls[name]); this.updateValueAndValidity(); this._onCollectionChange(); }; /** * Replace an existing control. * @param {?} name * @param {?} control * @return {?} */ FormGroup.prototype.setControl = function (name, control) { if (this.controls[name]) this.controls[name]._registerOnCollectionChange(function () { }); delete (this.controls[name]); if (control) this.registerControl(name, control); this.updateValueAndValidity(); this._onCollectionChange(); }; /** * Check whether there is an enabled control with the given name in the group. * * It will return false for disabled controls. If you'd like to check for * existence in the group only, use {\@link AbstractControl.get} instead. * @param {?} controlName * @return {?} */ FormGroup.prototype.contains = function (controlName) { return this.controls.hasOwnProperty(controlName) && this.controls[controlName].enabled; }; /** * Sets the value of the {\@link FormGroup}. It accepts an object that matches * the structure of the group, with control names as keys. * * This method performs strict checks, so it will throw an error if you try * to set the value of a control that doesn't exist or if you exclude the * value of a control. * * ### Example * * ``` * const form = new FormGroup({ * first: new FormControl(), * last: new FormControl() * }); * console.log(form.value); // {first: null, last: null} * * form.setValue({first: 'Nancy', last: 'Drew'}); * console.log(form.value); // {first: 'Nancy', last: 'Drew'} * * ``` * @param {?} value * @param {?=} __1 * @return {?} */ FormGroup.prototype.setValue = function (value, _a) { var _this = this; var _b = _a === void 0 ? {} : _a, onlySelf = _b.onlySelf, emitEvent = _b.emitEvent; this._checkAllValuesPresent(value); Object.keys(value).forEach(function (name) { _this._throwIfControlMissing(name); _this.controls[name].setValue(value[name], { onlySelf: true, emitEvent: emitEvent }); }); this.updateValueAndValidity({ onlySelf: onlySelf, emitEvent: emitEvent }); }; /** * Patches the value of the {\@link FormGroup}. It accepts an object with control * names as keys, and will do its best to match the values to the correct controls * in the group. * * It accepts both super-sets and sub-sets of the group without throwing an error. * * ### Example * * ``` * const form = new FormGroup({ * first: new FormControl(), * last: new FormControl() * }); * console.log(form.value); // {first: null, last: null} * * form.patchValue({first: 'Nancy'}); * console.log(form.value); // {first: 'Nancy', last: null} * * ``` * @param {?} value * @param {?=} __1 * @return {?} */ FormGroup.prototype.patchValue = function (value, _a) { var _this = this; var _b = _a === void 0 ? {} : _a, onlySelf = _b.onlySelf, emitEvent = _b.emitEvent; Object.keys(value).forEach(function (name) { if (_this.controls[name]) { _this.controls[name].patchValue(value[name], { onlySelf: true, emitEvent: emitEvent }); } }); this.updateValueAndValidity({ onlySelf: onlySelf, emitEvent: emitEvent }); }; /** * Resets the {\@link FormGroup}. This means by default: * * * The group and all descendants are marked `pristine` * * The group and all descendants are marked `untouched` * * The value of all descendants will be null or null maps * * You can also reset to a specific form state by passing in a map of states * that matches the structure of your form, with control names as keys. The state * can be a standalone value or a form state object with both a value and a disabled * status. * * ### Example * * ```ts * this.form.reset({first: 'name', last: 'last name'}); * * console.log(this.form.value); // {first: 'name', last: 'last name'} * ``` * * - OR - * * ``` * this.form.reset({ * first: {value: 'name', disabled: true}, * last: 'last' * }); * * console.log(this.form.value); // {first: 'name', last: 'last name'} * console.log(this.form.get('first').status); // 'DISABLED' * ``` * @param {?=} value * @param {?=} __1 * @return {?} */ FormGroup.prototype.reset = function (value, _a) { if (value === void 0) { value = {}; } var _b = _a === void 0 ? {} : _a, onlySelf = _b.onlySelf, emitEvent = _b.emitEvent; this._forEachChild(function (control, name) { control.reset(value[name], { onlySelf: true, emitEvent: emitEvent }); }); this.updateValueAndValidity({ onlySelf: onlySelf, emitEvent: emitEvent }); this._updatePristine({ onlySelf: onlySelf }); this._updateTouched({ onlySelf: onlySelf }); }; /** * The aggregate value of the {\@link FormGroup}, including any disabled controls. * * If you'd like to include all values regardless of disabled status, use this method. * Otherwise, the `value` property is the best way to get the value of the group. * @return {?} */ FormGroup.prototype.getRawValue = function () { return this._reduceChildren({}, function (acc, control, name) { acc[name] = control.value; return acc; }); }; /** * \@internal * @param {?} name * @return {?} */ FormGroup.prototype._throwIfControlMissing = function (name) { if (!Object.keys(this.controls).length) { throw new Error("\n There are no form controls registered with this group yet. If you're using ngModel,\n you may want to check next tick (e.g. use setTimeout).\n "); } if (!this.controls[name]) { throw new Error("Cannot find form control with name: " + name + "."); } }; /** * \@internal * @param {?} cb * @return {?} */ FormGroup.prototype._forEachChild = function (cb) { var _this = this; Object.keys(this.controls).forEach(function (k) { return cb(_this.controls[k], k); }); }; /** * \@internal * @return {?} */ FormGroup.prototype._setUpControls = function () { var _this = this; this._forEachChild(function (control) { control.setParent(_this); control._registerOnCollectionChange(_this._onCollectionChange); }); }; /** * \@internal * @return {?} */ FormGroup.prototype._updateValue = function () { this._value = this._reduceValue(); }; /** * \@internal * @param {?} condition * @return {?} */ FormGroup.prototype._anyControls = function (condition) { var _this = this; var /** @type {?} */ res = false; this._forEachChild(function (control, name) { res = res || (_this.contains(name) && condition(control)); }); return res; }; /** * \@internal * @return {?} */ FormGroup.prototype._reduceValue = function () { var _this = this; return this._reduceChildren({}, function (acc, control, name) { if (control.enabled || _this.disabled) { acc[name] = control.value; } return acc; }); }; /** * \@internal * @param {?} initValue * @param {?} fn * @return {?} */ FormGroup.prototype._reduceChildren = function (initValue, fn) { var /** @type {?} */ res = initValue; this._forEachChild(function (control, name) { res = fn(res, control, name); }); return res; }; /** * \@internal * @return {?} */ FormGroup.prototype._allControlsDisabled = function () { for (var _i = 0, _a = Object.keys(this.controls); _i < _a.length; _i++) { var controlName = _a[_i]; if (this.controls[controlName].enabled) { return false; } } return Object.keys(this.controls).length > 0 || this.disabled; }; /** * \@internal * @param {?} value * @return {?} */ FormGroup.prototype._checkAllValuesPresent = function (value) { this._forEachChild(function (control, name) { if (value[name] === undefined) { throw new Error("Must supply a value for form control with name: '" + name + "'."); } }); }; return FormGroup; }(AbstractControl)); function FormGroup_tsickle_Closure_declarations() { /** @type {?} */ FormGroup.prototype.controls; } /** * \@whatItDoes Tracks the value and validity state of an array of {\@link FormControl} * instances. * * A `FormArray` aggregates the values of each child {\@link FormControl} into an array. * It calculates its status by reducing the statuses of its children. For example, if one of * the controls in a `FormArray` is invalid, the entire array becomes invalid. * * `FormArray` is one of the three fundamental building blocks used to define forms in Angular, * along with {\@link FormControl} and {\@link FormGroup}. * * \@howToUse * * When instantiating a {\@link FormArray}, pass in an array of child controls as the first * argument. * * ### Example * * ``` * const arr = new FormArray([ * new FormControl('Nancy', Validators.minLength(2)), * new FormControl('Drew'), * ]); * * console.log(arr.value); // ['Nancy', 'Drew'] * console.log(arr.status); // 'VALID' * ``` * * You can also include array-level validators as the second arg, or array-level async * validators as the third arg. These come in handy when you want to perform validation * that considers the value of more than one child control. * * ### Adding or removing controls * * To change the controls in the array, use the `push`, `insert`, or `removeAt` methods * in `FormArray` itself. These methods ensure the controls are properly tracked in the * form's hierarchy. Do not modify the array of `AbstractControl`s used to instantiate * the `FormArray` directly, as that will result in strange and unexpected behavior such * as broken change detection. * * * **npm package**: `\@angular/forms` * * \@stable */ export var FormArray = (function (_super) { __extends(FormArray, _super); /** * @param {?} controls * @param {?=} validator * @param {?=} asyncValidator */ function FormArray(controls, validator, asyncValidator) { if (validator === void 0) { validator = null; } if (asyncValidator === void 0) { asyncValidator = null; } _super.call(this, validator, asyncValidator); this.controls = controls; this._initObservables(); this._setUpControls(); this.updateValueAndValidity({ onlySelf: true, emitEvent: false }); } /** * Get the {\@link AbstractControl} at the given `index` in the array. * @param {?} index * @return {?} */ FormArray.prototype.at = function (index) { return this.controls[index]; }; /** * Insert a new {\@link AbstractControl} at the end of the array. * @param {?} control * @return {?} */ FormArray.prototype.push = function (control) { this.controls.push(control); this._registerControl(control); this.updateValueAndValidity(); this._onCollectionChange(); }; /** * Insert a new {\@link AbstractControl} at the given `index` in the array. * @param {?} index * @param {?} control * @return {?} */ FormArray.prototype.insert = function (index, control) { this.controls.splice(index, 0, control); this._registerControl(control); this.updateValueAndValidity(); this._onCollectionChange(); }; /** * Remove the control at the given `index` in the array. * @param {?} index * @return {?} */ FormArray.prototype.removeAt = function (index) { if (this.controls[index]) this.controls[index]._registerOnCollectionChange(function () { }); this.controls.splice(index, 1); this.updateValueAndValidity(); this._onCollectionChange(); }; /** * Replace an existing control. * @param {?} index * @param {?} control * @return {?} */ FormArray.prototype.setControl = function (index, control) { if (this.controls[index]) this.controls[index]._registerOnCollectionChange(function () { }); this.controls.splice(index, 1); if (control) { this.controls.splice(index, 0, control); this._registerControl(control); } this.updateValueAndValidity(); this._onCollectionChange(); }; Object.defineProperty(FormArray.prototype, "length", { /** * Length of the control array. * @return {?} */ get: function () { return this.controls.length; }, enumerable: true, configurable: true }); /** * Sets the value of the {\@link FormArray}. It accepts an array that matches * the structure of the control. * * This method performs strict checks, so it will throw an error if you try * to set the value of a control that doesn't exist or if you exclude the * value of a control. * * ### Example * * ``` * const arr = new FormArray([ * new FormControl(), * new FormControl() * ]); * console.log(arr.value); // [null, null] * * arr.setValue(['Nancy', 'Drew']); * console.log(arr.value); // ['Nancy', 'Drew'] * ``` * @param {?} value * @param {?=} __1 * @return {?} */ FormArray.prototype.setValue = function (value, _a) { var _this = this; var _b = _a === void 0 ? {} : _a, onlySelf = _b.onlySelf, emitEvent = _b.emitEvent; this._checkAllValuesPresent(value); value.forEach(function (newValue, index) { _this._throwIfControlMissing(index); _this.at(index).setValue(newValue, { onlySelf: true, emitEvent: emitEvent }); }); this.updateValueAndValidity({ onlySelf: onlySelf, emitEvent: emitEvent }); }; /** * Patches the value of the {\@link FormArray}. It accepts an array that matches the * structure of the control, and will do its best to match the values to the correct * controls in the group. * * It accepts both super-sets and sub-sets of the array without throwing an error. * * ### Example * * ``` * const arr = new FormArray([ * new FormControl(), * new FormControl() * ]); * console.log(arr.value); // [null, null] * * arr.patchValue(['Nancy']); * console.log(arr.value); // ['Nancy', null] * ``` * @param {?} value * @param {?=} __1 * @return {?} */ FormArray.prototype.patchValue = function (value, _a) { var _this = this; var _b = _a === void 0 ? {} : _a, onlySelf = _b.onlySelf, emitEvent = _b.emitEvent; value.forEach(function (newValue, index) { if (_this.at(index)) { _this.at(index).patchValue(newValue, { onlySelf: true, emitEvent: emitEvent }); } }); this.updateValueAndValidity({ onlySelf: onlySelf, emitEvent: emitEvent }); }; /** * Resets the {\@link FormArray}. This means by default: * * * The array and all descendants are marked `pristine` * * The array and all descendants are marked `untouched` * * The value of all descendants will be null or null maps * * You can also reset to a specific form state by passing in an array of states * that matches the structure of the control. The state can be a standalone value * or a form state object with both a value and a disabled status. * * ### Example * * ```ts * this.arr.reset(['name', 'last name']); * * console.log(this.arr.value); // ['name', 'last name'] * ``` * * - OR - * * ``` * this.arr.reset([ * {value: 'name', disabled: true}, * 'last' * ]); * * console.log(this.arr.value); // ['name', 'last name'] * console.log(this.arr.get(0).status); // 'DISABLED' * ``` * @param {?=} value * @param {?=} __1 * @return {?} */ FormArray.prototype.reset = function (value, _a) { if (value === void 0) { value = []; } var _b = _a === void 0 ? {} : _a, onlySelf = _b.onlySelf, emitEvent = _b.emitEvent; this._forEachChild(function (control, index) { control.reset(value[index], { onlySelf: true, emitEvent: emitEvent }); }); this.updateValueAndValidity({ onlySelf: onlySelf, emitEvent: emitEvent }); this._updatePristine({ onlySelf: onlySelf }); this._updateTouched({ onlySelf: onlySelf }); }; /** * The aggregate value of the array, including any disabled controls. * * If you'd like to include all values regardless of disabled status, use this method. * Otherwise, the `value` property is the best way to get the value of the array. * @return {?} */ FormArray.prototype.getRawValue = function () { return this.controls.map(function (control) { return control.value; }); }; /** * \@internal * @param {?} index * @return {?} */ FormArray.prototype._throwIfControlMissing = function (index) { if (!this.controls.length) { throw new Error("\n There are no form controls registered with this array yet. If you're using ngModel,\n you may want to check next tick (e.g. use setTimeout).\n "); } if (!this.at(index)) { throw new Error("Cannot find form control at index " + index); } }; /** * \@internal * @param {?} cb * @return {?} */ FormArray.prototype._forEachChild = function (cb) { this.controls.forEach(function (control, index) { cb(control, index); }); }; /** * \@internal * @return {?} */ FormArray.prototype._updateValue = function () { var _this = this; this._value = this.controls.filter(function (control) { return control.enabled || _this.disabled; }) .map(function (control) { return control.value; }); }; /** * \@internal * @param {?} condition * @return {?} */ FormArray.prototype._anyControls = function (condition) { return this.controls.some(function (control) { return control.enabled && condition(control); }); }; /** * \@internal * @return {?} */ FormArray.prototype._setUpControls = function () { var _this = this; this._forEachChild(function (control) { return _this._registerControl(control); }); }; /** * \@internal * @param {?} value * @return {?} */ FormArray.prototype._checkAllValuesPresent = function (value) { this._forEachChild(function (control, i) { if (value[i] === undefined) { throw new Error("Must supply a value for form control at index: " + i + "."); } }); }; /** * \@internal * @return {?} */ FormArray.prototype._allControlsDisabled = function () { for (var _i = 0, _a = this.controls; _i < _a.length; _i++) { var control = _a[_i]; if (control.enabled) return false; } return this.controls.length > 0 || this.disabled; }; /** * @param {?} control * @return {?} */ FormArray.prototype._registerControl = function (control) { control.setParent(this); control._registerOnCollectionChange(this._onCollectionChange); }; return FormArray; }(AbstractControl)); function FormArray_tsickle_Closure_declarations() { /** @type {?} */ FormArray.prototype.controls; } //# sourceMappingURL=model.js.map