/** * @license * Copyright Google LLC 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 */ import { AsyncValidatorFn, ValidatorFn } from '../directives/validators'; import { AbstractControl, AbstractControlOptions, ɵRawValue, ɵTypedOrUntyped, ɵValue } from './abstract_model'; /** * FormArrayValue extracts the type of `.value` from a FormArray's element type, and wraps it in an * array. * * Angular uses this type internally to support Typed Forms; do not use it directly. The untyped * case falls back to any[]. */ export type ɵFormArrayValue> = ɵTypedOrUntyped>, any[]>; /** * FormArrayRawValue extracts the type of `.getRawValue()` from a FormArray's element type, and * wraps it in an array. The untyped case falls back to any[]. * * Angular uses this type internally to support Typed Forms; do not use it directly. */ export type ɵFormArrayRawValue> = ɵTypedOrUntyped>, any[]>; /** * Tracks the value and validity state of an array of `FormControl`, * `FormGroup` or `FormArray` instances. * * A `FormArray` aggregates the values of each child `FormControl` into an array. * It calculates its status by reducing the status values of its children. For example, if one of * the controls in a `FormArray` is invalid, the entire array becomes invalid. * * `FormArray` accepts one generic argument, which is the type of the controls inside. * If you need a heterogenous array, use {@link UntypedFormArray}. * * `FormArray` is one of the four fundamental building blocks used to define forms in Angular, * along with `FormControl`, `FormGroup`, and `FormRecord`. * * @usageNotes * * ### Create an array of form controls * * ``` * const arr = new FormArray([ * new FormControl('Nancy', Validators.minLength(2)), * new FormControl('Drew'), * ]); * * console.log(arr.value); // ['Nancy', 'Drew'] * console.log(arr.status); // 'VALID' * ``` * * ### Create a form array with array-level validators * * You include array-level validators and async validators. These come in handy * when you want to perform validation that considers the value of more than one child * control. * * The two types of validators are passed in separately as the second and third arg * respectively, or together as part of an options object. * * ``` * const arr = new FormArray([ * new FormControl('Nancy'), * new FormControl('Drew') * ], {validators: myValidator, asyncValidators: myAsyncValidator}); * ``` * * ### Set the updateOn property for all controls in a form array * * The options object is used to set a default value for each child * control's `updateOn` property. If you set `updateOn` to `'blur'` at the * array level, all child controls default to 'blur', unless the child * has explicitly specified a different `updateOn` value. * * ```ts * const arr = new FormArray([ * new FormControl() * ], {updateOn: 'blur'}); * ``` * * ### Adding or removing controls from a form array * * To change the controls in the array, use the `push`, `insert`, `removeAt` or `clear` 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 result in strange and unexpected behavior such * as broken change detection. * * @publicApi */ export declare class FormArray = any> extends AbstractControl<ɵTypedOrUntyped, any>, ɵTypedOrUntyped, any>> { /** * Creates a new `FormArray` instance. * * @param controls An array of child controls. Each child control is given an index * where it is registered. * * @param validatorOrOpts A synchronous validator function, or an array of * such functions, or an `AbstractControlOptions` object that contains validation functions * and a validation trigger. * * @param asyncValidator A single async validator or array of async validator functions * */ constructor(controls: Array, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null); controls: ɵTypedOrUntyped, Array>>; /** * Get the `AbstractControl` at the given `index` in the array. * * @param index Index in the array to retrieve the control. If `index` is negative, it will wrap * around from the back, and if index is greatly negative (less than `-length`), the result is * undefined. This behavior is the same as `Array.at(index)`. */ at(index: number): ɵTypedOrUntyped>; /** * Insert a new `AbstractControl` at the end of the array. * * @param control Form control to be inserted * @param options Specifies whether this FormArray instance should emit events after a new * control is added. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and * `valueChanges` observables emit events with the latest status and value when the control is * inserted. When false, no events are emitted. */ push(control: TControl, options?: { emitEvent?: boolean; }): void; /** * Insert a new `AbstractControl` at the given `index` in the array. * * @param index Index in the array to insert the control. If `index` is negative, wraps around * from the back. If `index` is greatly negative (less than `-length`), prepends to the array. * This behavior is the same as `Array.splice(index, 0, control)`. * @param control Form control to be inserted * @param options Specifies whether this FormArray instance should emit events after a new * control is inserted. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and * `valueChanges` observables emit events with the latest status and value when the control is * inserted. When false, no events are emitted. */ insert(index: number, control: TControl, options?: { emitEvent?: boolean; }): void; /** * Remove the control at the given `index` in the array. * * @param index Index in the array to remove the control. If `index` is negative, wraps around * from the back. If `index` is greatly negative (less than `-length`), removes the first * element. This behavior is the same as `Array.splice(index, 1)`. * @param options Specifies whether this FormArray instance should emit events after a * control is removed. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and * `valueChanges` observables emit events with the latest status and value when the control is * removed. When false, no events are emitted. */ removeAt(index: number, options?: { emitEvent?: boolean; }): void; /** * Replace an existing control. * * @param index Index in the array to replace the control. If `index` is negative, wraps around * from the back. If `index` is greatly negative (less than `-length`), replaces the first * element. This behavior is the same as `Array.splice(index, 1, control)`. * @param control The `AbstractControl` control to replace the existing control * @param options Specifies whether this FormArray instance should emit events after an * existing control is replaced with a new one. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and * `valueChanges` observables emit events with the latest status and value when the control is * replaced with a new one. When false, no events are emitted. */ setControl(index: number, control: TControl, options?: { emitEvent?: boolean; }): void; /** * Length of the control array. */ get length(): number; /** * Sets the value of the `FormArray`. It accepts an array that matches * the structure of the control. * * This method performs strict checks, and throws 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. * * @usageNotes * ### Set the values for the controls in the form array * * ``` * 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 Array of values for the controls * @param options Configure options that determine how the control propagates changes and * emits events after the value changes * * * `onlySelf`: When true, each change only affects this control, and not its parent. Default * is false. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and * `valueChanges` * observables emit events with the latest status and value when the control value is updated. * When false, no events are emitted. * The configuration options are passed to the {@link AbstractControl#updateValueAndValidity * updateValueAndValidity} method. */ setValue(value: ɵFormArrayRawValue, options?: { onlySelf?: boolean; emitEvent?: boolean; }): void; /** * Patches the value of the `FormArray`. It accepts an array that matches the * structure of the control, and does 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. * * @usageNotes * ### Patch the values for controls in a form array * * ``` * 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 Array of latest values for the controls * @param options Configure options that determine how the control propagates changes and * emits events after the value changes * * * `onlySelf`: When true, each change only affects this control, and not its parent. Default * is false. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and * `valueChanges` observables emit events with the latest status and value when the control * value is updated. When false, no events are emitted. The configuration options are passed to * the {@link AbstractControl#updateValueAndValidity updateValueAndValidity} method. */ patchValue(value: ɵFormArrayValue, options?: { onlySelf?: boolean; emitEvent?: boolean; }): void; /** * Resets the `FormArray` and all descendants are marked `pristine` and `untouched`, and the * value of all descendants to null or null maps. * * You reset to a specific form state by passing in an array of states * that matches the structure of the control. The state is a standalone value * or a form state object with both a value and a disabled status. * * @usageNotes * ### Reset the values in a form array * * ```ts * const arr = new FormArray([ * new FormControl(), * new FormControl() * ]); * arr.reset(['name', 'last name']); * * console.log(arr.value); // ['name', 'last name'] * ``` * * ### Reset the values in a form array and the disabled status for the first control * * ``` * arr.reset([ * {value: 'name', disabled: true}, * 'last' * ]); * * console.log(arr.value); // ['last'] * console.log(arr.at(0).status); // 'DISABLED' * ``` * * @param value Array of values for the controls * @param options Configure options that determine how the control propagates changes and * emits events after the value changes * * * `onlySelf`: When true, each change only affects this control, and not its parent. Default * is false. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and * `valueChanges` * observables emit events with the latest status and value when the control is reset. * When false, no events are emitted. * The configuration options are passed to the {@link AbstractControl#updateValueAndValidity * updateValueAndValidity} method. */ reset(value?: ɵTypedOrUntyped, any>, options?: { onlySelf?: boolean; emitEvent?: boolean; }): void; /** * The aggregate value of the array, including any disabled controls. * * Reports all values regardless of disabled status. */ getRawValue(): ɵFormArrayRawValue; /** * Remove all controls in the `FormArray`. * * @param options Specifies whether this FormArray instance should emit events after all * controls are removed. * * `emitEvent`: When true or not supplied (the default), both the `statusChanges` and * `valueChanges` observables emit events with the latest status and value when all controls * in this FormArray instance are removed. When false, no events are emitted. * * @usageNotes * ### Remove all elements from a FormArray * * ```ts * const arr = new FormArray([ * new FormControl(), * new FormControl() * ]); * console.log(arr.length); // 2 * * arr.clear(); * console.log(arr.length); // 0 * ``` * * It's a simpler and more efficient alternative to removing all elements one by one: * * ```ts * const arr = new FormArray([ * new FormControl(), * new FormControl() * ]); * * while (arr.length) { * arr.removeAt(0); * } * ``` */ clear(options?: { emitEvent?: boolean; }): void; /** * Adjusts a negative index by summing it with the length of the array. For very negative * indices, the result may remain negative. * @internal */ private _adjustIndex; /** @internal */ _syncPendingControls(): boolean; /** @internal */ _forEachChild(cb: (c: AbstractControl, index: number) => void): void; /** @internal */ _updateValue(): void; /** @internal */ _anyControls(condition: (c: AbstractControl) => boolean): boolean; /** @internal */ _setUpControls(): void; /** @internal */ _allControlsDisabled(): boolean; private _registerControl; /** @internal */ _find(name: string | number): AbstractControl | null; } interface UntypedFormArrayCtor { new (controls: AbstractControl[], validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null): UntypedFormArray; /** * The presence of an explicit `prototype` property provides backwards-compatibility for apps that * manually inspect the prototype chain. */ prototype: FormArray; } /** * UntypedFormArray is a non-strongly-typed version of `FormArray`, which * permits heterogenous controls. */ export type UntypedFormArray = FormArray; export declare const UntypedFormArray: UntypedFormArrayCtor; /** * @description * Asserts that the given control is an instance of `FormArray` * * @publicApi */ export declare const isFormArray: (control: unknown) => control is FormArray; export {};