diff --git a/aio/content/guide/typed-forms.md b/aio/content/guide/typed-forms.md index 8329be8e298..7093729e635 100644 --- a/aio/content/guide/typed-forms.md +++ b/aio/content/guide/typed-forms.md @@ -72,10 +72,10 @@ email.reset(); console.log(email.value); // null ``` -TypeScript will enforce that you always handle the possibility that the control has become `null`. If you want to make this control non-nullable, you may use the `initialValueIsDefault` option. This will cause the control to reset to its intial value, instead of `null`: +TypeScript will enforce that you always handle the possibility that the control has become `null`. If you want to make this control non-nullable, you may use the `nonNullable` option. This will cause the control to reset to its intial value, instead of `null`: ```ts -const email = new FormControl('angularrox@gmail.com', {initialValueIsDefault: true}); +const email = new FormControl('angularrox@gmail.com', {nonNullable: true}); email.reset(); console.log(email.value); // angularrox@gmail.com ``` @@ -125,8 +125,8 @@ Consider again a login form: ```ts const login = new FormGroup({ - email: new FormControl('', {initialValueIsDefault: true}), - password: new FormControl('', {initialValueIsDefault: true}), + email: new FormControl('', {nonNullable: true}), + password: new FormControl('', {nonNullable: true}), }); ``` @@ -149,8 +149,8 @@ interface LoginForm { } const login = new FormGroup({ - email: new FormControl('', {initialValueIsDefault: true}), - password: new FormControl('', {initialValueIsDefault: true}), + email: new FormControl('', {nonNullable: true}), + password: new FormControl('', {nonNullable: true}), }); login.removeControl('password'); @@ -175,7 +175,7 @@ If you need a `FormGroup` that is both dynamic (open-ended) and heterogenous (th The `FormBuilder` class has been upgraded to support the new types as well, in the same manner as the above examples. -Additionally, an additional builder is available: `NonNullableFormBuilder`. This type is shorthand for specifying `{initialValueIsDefault: true}` on every control, and can eliminate significant boilerplate from large non-nullable forms. You can access it using the `nonNullable` property on a `FormBuilder`: +Additionally, an additional builder is available: `NonNullableFormBuilder`. This type is shorthand for specifying `{nonNullable: true}` on every control, and can eliminate significant boilerplate from large non-nullable forms. You can access it using the `nonNullable` property on a `FormBuilder`: ```ts const fb = new FormBuilder(); @@ -185,7 +185,7 @@ const login = fb.nonNullable.group({ }); ``` -On the above example, both inner controls will be non-nullable (i.e. `initialValueIsDefault` will be set). +On the above example, both inner controls will be non-nullable (i.e. `nonNullable` will be set). You can also inject it using the name `NonNullableFormBuilder`. diff --git a/goldens/public-api/forms/index.md b/goldens/public-api/forms/index.md index 5cff8f4cb1c..6bb84d0cd18 100644 --- a/goldens/public-api/forms/index.md +++ b/goldens/public-api/forms/index.md @@ -277,11 +277,15 @@ export class FormArrayName extends ControlContainer implements OnInit, OnDestroy // @public export class FormBuilder { array(controls: Array, validatorOrOpts?: ValidatorFn | ValidatorFn[] | AbstractControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null): FormArray<ɵElement>; - // (undocumented) + // @deprecated (undocumented) control(formState: T | FormControlState, opts: FormControlOptions & { initialValueIsDefault: true; }): FormControl; // (undocumented) + control(formState: T | FormControlState, opts: FormControlOptions & { + nonNullable: true; + }): FormControl; + // (undocumented) control(formState: T | FormControlState, validatorOrOpts?: ValidatorFn | ValidatorFn[] | FormControlOptions | null, asyncValidator?: AsyncValidatorFn | AsyncValidatorFn[] | null): FormControl; group(controls: T, options?: AbstractControlOptions | null): FormGroup<{ [K in keyof T]: ɵElement; @@ -374,7 +378,9 @@ export class FormControlName extends NgControl implements OnChanges, OnDestroy { // @public export interface FormControlOptions extends AbstractControlOptions { + // @deprecated (undocumented) initialValueIsDefault?: boolean; + nonNullable?: boolean; } // @public diff --git a/packages/forms/src/form_builder.ts b/packages/forms/src/form_builder.ts index 90d9368fa81..d1896a43650 100644 --- a/packages/forms/src/form_builder.ts +++ b/packages/forms/src/form_builder.ts @@ -27,7 +27,8 @@ function isFormControlOptions(options: FormControlOptions|{[key: string]: any}|n undefined): options is FormControlOptions { return !!options && (isAbstractControlOptions(options) || - (options as FormControlOptions).initialValueIsDefault !== undefined); + (options as FormControlOptions).initialValueIsDefault !== undefined || + (options as FormControlOptions).nonNullable !== undefined); } /** @@ -85,7 +86,7 @@ export class FormBuilder { /** * @description * Returns a FormBuilder in which automatically constructed @see FormControl} elements - * have `{initialValueIsDefault: true}` and are non-nullable. + * have `{nonNullable: true}` and are non-nullable. * * **Constructing non-nullable controls** * @@ -205,10 +206,14 @@ export class FormBuilder { return new FormGroup(reducedControls, {asyncValidators, updateOn, validators}) as any; } + /** @deprecated Use `nonNullable` instead. */ control(formState: T|FormControlState, opts: FormControlOptions&{ initialValueIsDefault: true }): FormControl; + control(formState: T|FormControlState, opts: FormControlOptions&{nonNullable: true}): + FormControl; + control( formState: T|FormControlState, validatorOrOpts?: ValidatorFn|ValidatorFn[]|FormControlOptions|null, @@ -217,7 +222,7 @@ export class FormBuilder { /** * @description * Construct a new `FormControl` with the given state, validators and options. Set - * `{initialValueIsDefault: true}` in the options to get a non-nullable control. Otherwise, the + * `{nonNullable: true}` in the options to get a non-nullable control. Otherwise, the * control will be nullable. Accepts a single generic argument, which is the type of the * control's value. * @@ -256,7 +261,7 @@ export class FormBuilder { newOptions.validators = validatorOrOpts; newOptions.asyncValidators = asyncValidator; } - return new FormControl(formState, {...newOptions, initialValueIsDefault: true}); + return new FormControl(formState, {...newOptions, nonNullable: true}); } /** @@ -314,7 +319,7 @@ export class FormBuilder { /** * @description * `NonNullableFormBuilder` is similar to {@link FormBuilder}, but automatically constructed - * {@link FormControl} elements have `{initialValueIsDefault: true}` and are non-nullable. + * {@link FormControl} elements have `{nonNullable: true}` and are non-nullable. * * @publicApi */ @@ -325,7 +330,7 @@ export class FormBuilder { export abstract class NonNullableFormBuilder { /** * Similar to `FormBuilder#group`, except any implicitly constructed `FormControl` - * will be non-nullable (i.e. it will have `initialValueIsDefault` set to true). Note + * will be non-nullable (i.e. it will have `nonNullable` set to true). Note * that already-constructed controls will not be altered. */ abstract group( @@ -335,7 +340,7 @@ export abstract class NonNullableFormBuilder { /** * Similar to `FormBuilder#array`, except any implicitly constructed `FormControl` - * will be non-nullable (i.e. it will have `initialValueIsDefault` set to true). Note + * will be non-nullable (i.e. it will have `nonNullable` set to true). Note * that already-constructed controls will not be altered. */ abstract array( @@ -344,7 +349,7 @@ export abstract class NonNullableFormBuilder { /** * Similar to `FormBuilder#control`, except this overridden version of `control` forces - * `initialValueIsDefault` to be `true`, resulting in the control always being non-nullable. + * `nonNullable` to be `true`, resulting in the control always being non-nullable. */ abstract control( formState: T|FormControlState, diff --git a/packages/forms/src/model/form_control.ts b/packages/forms/src/model/form_control.ts index 09a2cd69d50..1002b597816 100644 --- a/packages/forms/src/model/form_control.ts +++ b/packages/forms/src/model/form_control.ts @@ -37,6 +37,11 @@ export interface FormControlOptions extends AbstractControlOptions { * When a FormControl is reset without an explicit value, its value reverts to * its default value. */ + nonNullable?: boolean; + + /** + * @deprecated Use `nonNullable` instead. + */ initialValueIsDefault?: boolean; } @@ -50,7 +55,7 @@ export interface FormControlOptions extends AbstractControlOptions { * * `FormControl` takes a single generic argument, which describes the type of its value. This * argument always implicitly includes `null` because the control can be reset. To change this - * behavior, set `initialValueIsDefault` or see the usage notes below. + * behavior, set `nonNullable` or see the usage notes below. * * See [usage examples below](#usage-notes). * @@ -114,7 +119,7 @@ export interface FormControlOptions extends AbstractControlOptions { * * You might notice that `null` is always added to the type of the control. * This is because the control will become `null` if you call `reset`. You can change - * this behavior by setting `{initialValueIsDefault: true}`. + * this behavior by setting `{nonNullable: true}`. * * ### Configure the control to update on a blur event * @@ -151,10 +156,10 @@ export interface FormControlOptions extends AbstractControlOptions { * ### Reset the control to its initial value * * If you wish to always reset the control to its initial value (instead of null), - * you can pass the `initialValueIsDefault` option: + * you can pass the `nonNullable` option: * * ``` - * const control = new FormControl('Nancy', {initialValueIsDefault: true}); + * const control = new FormControl('Nancy', {nonNullable: true}); * * console.log(control.value); // 'Nancy' * @@ -180,7 +185,7 @@ export interface FormControlOptions extends AbstractControlOptions { export interface FormControl extends AbstractControl { /** * The default value of this FormControl, used whenever the control is reset without an explicit - * value. See {@link FormControlOptions#initialValueIsDefault} for more information on configuring + * value. See {@link FormControlOptions#nonNullable} for more information on configuring * a default value. */ readonly defaultValue: TValue; @@ -246,7 +251,7 @@ export interface FormControl extends AbstractControl { /** * Resets the form control, marking it `pristine` and `untouched`, and resetting * the value. The new value will be the provided value (if passed), `null`, or the initial value - * if `initialValueIsDefault` was set in the constructor via {@link FormControlOptions}. + * if `nonNullable` was set in the constructor via {@link FormControlOptions}. * * ```ts * // By default, the control will reset to null. @@ -254,11 +259,11 @@ export interface FormControl extends AbstractControl { * dog.reset(); // dog.value is null * * // If this flag is set, the control will instead reset to the initial value. - * const cat = new FormControl('tabby', {initialValueIsDefault: true}); + * const cat = new FormControl('tabby', {nonNullable: true}); * cat.reset(); // cat.value is "tabby" * * // A value passed to reset always takes precedence. - * const fish = new FormControl('finn', {initialValueIsDefault: true}); + * const fish = new FormControl('finn', {nonNullable: true}); * fish.reset('bubble'); // fish.value is "bubble" * ``` * @@ -368,6 +373,11 @@ export interface ɵFormControlCtor { * * @param asyncValidator A single async validator or array of async validator functions */ + new(value: FormControlState|T, opts: FormControlOptions&{nonNullable: true}): + FormControl; + /** + * @deprecated Use `nonNullable` instead. + */ new(value: FormControlState|T, opts: FormControlOptions&{ initialValueIsDefault: true }): FormControl; @@ -421,7 +431,8 @@ export const FormControl: ɵFormControlCtor = // `emitEvent` to `true` to allow that during the control creation process. emitEvent: !!this.asyncValidator }); - if (isOptionsObj(validatorOrOpts) && validatorOrOpts.initialValueIsDefault) { + if (isOptionsObj(validatorOrOpts) && + (validatorOrOpts.nonNullable || validatorOrOpts.initialValueIsDefault)) { if (isFormControlState(formState)) { this.defaultValue = formState.value; } else { diff --git a/packages/forms/test/form_control_spec.ts b/packages/forms/test/form_control_spec.ts index 4e86a61578e..b50bdd35e92 100644 --- a/packages/forms/test/form_control_spec.ts +++ b/packages/forms/test/form_control_spec.ts @@ -817,7 +817,7 @@ describe('FormControl', () => { }); it('should reset to the initial value if specified in FormControlOptions', () => { - const c2 = new FormControl('foo', {initialValueIsDefault: true}); + const c2 = new FormControl('foo', {nonNullable: true}); expect(c2.value).toBe('foo'); expect(c2.defaultValue).toBe('foo'); @@ -829,7 +829,7 @@ describe('FormControl', () => { expect(c2.value).toBe('foo'); expect(c2.defaultValue).toBe('foo'); - const c3 = new FormControl('foo', {initialValueIsDefault: false}); + const c3 = new FormControl('foo', {nonNullable: false}); expect(c3.value).toBe('foo'); expect(c3.defaultValue).toBe(null); @@ -858,7 +858,7 @@ describe('FormControl', () => { it('should not alter the disabled state when resetting, even if a default value is provided', () => { - const c2 = new FormControl({value: 'foo', disabled: true}, {initialValueIsDefault: true}); + const c2 = new FormControl({value: 'foo', disabled: true}, {nonNullable: true}); expect(c2.value).toBe('foo'); expect(c2.defaultValue).toBe('foo'); expect(c2.disabled).toBe(true); diff --git a/packages/forms/test/typed_integration_spec.ts b/packages/forms/test/typed_integration_spec.ts index 0092e7ba9e2..b6a3dd24c72 100644 --- a/packages/forms/test/typed_integration_spec.ts +++ b/packages/forms/test/typed_integration_spec.ts @@ -16,7 +16,7 @@ import {FormRecord} from '../src/model/form_group'; describe('Typed Class', () => { describe('FormControl', () => { it('supports inferred controls', () => { - const c = new FormControl('', {initialValueIsDefault: true}); + const c = new FormControl('', {nonNullable: true}); { type ValueType = string; let t: ValueType = c.value; @@ -37,7 +37,7 @@ describe('Typed Class', () => { }); it('supports explicit controls', () => { - const c = new FormControl('', {initialValueIsDefault: true}); + const c = new FormControl('', {nonNullable: true}); { type ValueType = string; let t: ValueType = c.value; @@ -56,7 +56,7 @@ describe('Typed Class', () => { }); it('supports explicit boolean controls', () => { - let c1: FormControl = new FormControl(false, {initialValueIsDefault: true}); + let c1: FormControl = new FormControl(false, {nonNullable: true}); }); it('supports empty controls', () => { @@ -88,7 +88,7 @@ describe('Typed Class', () => { c.reset(''); }); - it('should create a nullable control without {initialValueIsDefault: true}', () => { + it('should create a nullable control without {nonNullable: true}', () => { const c = new FormControl(''); { type ValueType = string|null; @@ -110,6 +110,25 @@ describe('Typed Class', () => { c.reset(''); }); + it('should allow deprecated option {initialValueIsDefault: true}', () => { + const c = new FormControl('', {initialValueIsDefault: true}); + { + type ValueType = string; + let t: ValueType = c.value; + let t1 = c.value; + t1 = null as unknown as ValueType; + } + { + type RawValueType = string; + let t: RawValueType = c.getRawValue(); + let t1 = c.getRawValue(); + t1 = null as unknown as RawValueType; + } + c.setValue(''); + c.reset(); + expect(c.value).toEqual(''); + }); + it('should not allow assignment to an incompatible control', () => { let fcs = new FormControl('bob'); let fcn = new FormControl(42); @@ -121,7 +140,7 @@ describe('Typed Class', () => { it('is assignable to AbstractControl', () => { let ac: AbstractControl; - ac = new FormControl(true, {initialValueIsDefault: true}); + ac = new FormControl(true, {nonNullable: true}); }); it('is assignable to UntypedFormControl', () => { @@ -134,8 +153,8 @@ describe('Typed Class', () => { describe('FormGroup', () => { it('supports inferred groups', () => { const c = new FormGroup({ - c: new FormControl('', {initialValueIsDefault: true}), - d: new FormControl(0, {initialValueIsDefault: true}) + c: new FormControl('', {nonNullable: true}), + d: new FormControl(0, {nonNullable: true}) }); { type ValueType = Partial<{c: string, d: number}>; @@ -149,9 +168,9 @@ describe('Typed Class', () => { let t1 = c.getRawValue(); t1 = null as unknown as RawValueType; } - c.registerControl('c', new FormControl('', {initialValueIsDefault: true})); - c.addControl('c', new FormControl('', {initialValueIsDefault: true})); - c.setControl('c', new FormControl('', {initialValueIsDefault: true})); + c.registerControl('c', new FormControl('', {nonNullable: true})); + c.addControl('c', new FormControl('', {nonNullable: true})); + c.setControl('c', new FormControl('', {nonNullable: true})); c.contains('c'); c.contains('foo'); // Contains checks always allowed c.setValue({c: '', d: 0}); @@ -161,8 +180,8 @@ describe('Typed Class', () => { it('supports explicit groups', () => { const c = new FormGroup<{c: FormControl, d: FormControl}>({ - c: new FormControl('', {initialValueIsDefault: true}), - d: new FormControl(0, {initialValueIsDefault: true}) + c: new FormControl('', {nonNullable: true}), + d: new FormControl(0, {nonNullable: true}) }); { type ValueType = Partial<{c: string, d: number}>; @@ -176,9 +195,9 @@ describe('Typed Class', () => { let t1 = c.getRawValue(); t1 = null as unknown as RawValueType; } - c.registerControl('c', new FormControl('', {initialValueIsDefault: true})); - c.addControl('c', new FormControl('', {initialValueIsDefault: true})); - c.setControl('c', new FormControl('', {initialValueIsDefault: true})); + c.registerControl('c', new FormControl('', {nonNullable: true})); + c.addControl('c', new FormControl('', {nonNullable: true})); + c.setControl('c', new FormControl('', {nonNullable: true})); c.contains('c'); c.setValue({c: '', d: 0}); c.patchValue({c: ''}); @@ -186,13 +205,13 @@ describe('Typed Class', () => { }); it('supports explicit groups with boolean types', () => { - const c0 = new FormGroup({a: new FormControl(true, {initialValueIsDefault: true})}); + const c0 = new FormGroup({a: new FormControl(true, {nonNullable: true})}); const c1: AbstractControl<{a?: boolean}, {a: boolean}> = - new FormGroup({a: new FormControl(true, {initialValueIsDefault: true})}); + new FormGroup({a: new FormControl(true, {nonNullable: true})}); // const c2: FormGroup<{a: FormControl}> = - // new FormGroup({a: new FormControl(true, {initialValueIsDefault: true})}); + // new FormGroup({a: new FormControl(true, {nonNullable: true})}); }); it('supports empty groups', () => { @@ -201,10 +220,8 @@ describe('Typed Class', () => { }); it('supports groups with nullable controls', () => { - const c = new FormGroup({ - c: new FormControl(''), - d: new FormControl('', {initialValueIsDefault: true}) - }); + const c = new FormGroup( + {c: new FormControl(''), d: new FormControl('', {nonNullable: true})}); { type ValueType = Partial<{c: string | null, d: string}>; let t: ValueType = c.value; @@ -232,8 +249,7 @@ describe('Typed Class', () => { it('supports groups with the default type', () => { let c: FormGroup; - let c2 = new FormGroup( - {c: new FormControl(''), d: new FormControl('', {initialValueIsDefault: true})}); + let c2 = new FormGroup({c: new FormControl(''), d: new FormControl('', {nonNullable: true})}); c = c2; expect(c.value.d).toBe(''); c.value; @@ -256,8 +272,7 @@ describe('Typed Class', () => { interface CatControls { lives: FormControl; } - const c = - new FormGroup({lives: new FormControl(9, {initialValueIsDefault: true})}); + const c = new FormGroup({lives: new FormControl(9, {nonNullable: true})}); { type ValueType = Partial; let t: ValueType = c.value; @@ -270,9 +285,9 @@ describe('Typed Class', () => { let t1 = c.getRawValue(); t1 = null as unknown as RawValueType; } - c.registerControl('lives', new FormControl(0, {initialValueIsDefault: true})); - c.addControl('lives', new FormControl(0, {initialValueIsDefault: true})); - c.setControl('lives', new FormControl(0, {initialValueIsDefault: true})); + c.registerControl('lives', new FormControl(0, {nonNullable: true})); + c.addControl('lives', new FormControl(0, {nonNullable: true})); + c.setControl('lives', new FormControl(0, {nonNullable: true})); c.contains('lives'); c.setValue({lives: 0}); c.patchValue({}); @@ -298,12 +313,12 @@ describe('Typed Class', () => { sister: FormGroup; } const bro = new FormGroup({ - name: new FormControl('bob', {initialValueIsDefault: true}), - lives: new FormControl(9, {initialValueIsDefault: true}) + name: new FormControl('bob', {nonNullable: true}), + lives: new FormControl(9, {nonNullable: true}) }); const sis = new FormGroup({ - name: new FormControl('lucy', {initialValueIsDefault: true}), - lives: new FormControl(9, {initialValueIsDefault: true}) + name: new FormControl('lucy', {nonNullable: true}), + lives: new FormControl(9, {nonNullable: true}) }); const litter = new FormGroup({ brother: bro, @@ -326,10 +341,8 @@ describe('Typed Class', () => { }); it('supports nested inferred groups', () => { - const c = new FormGroup({ - innerGroup: - new FormGroup({innerControl: new FormControl('', {initialValueIsDefault: true})}) - }); + const c = new FormGroup( + {innerGroup: new FormGroup({innerControl: new FormControl('', {nonNullable: true})})}); { type ValueType = Partial<{innerGroup: Partial<{innerControl: string}>}>; let t: ValueType = c.value; @@ -343,14 +356,11 @@ describe('Typed Class', () => { t1 = null as unknown as RawValueType; } c.registerControl( - 'innerGroup', - new FormGroup({innerControl: new FormControl('', {initialValueIsDefault: true})})); + 'innerGroup', new FormGroup({innerControl: new FormControl('', {nonNullable: true})})); c.addControl( - 'innerGroup', - new FormGroup({innerControl: new FormControl('', {initialValueIsDefault: true})})); + 'innerGroup', new FormGroup({innerControl: new FormControl('', {nonNullable: true})})); c.setControl( - 'innerGroup', - new FormGroup({innerControl: new FormControl('', {initialValueIsDefault: true})})); + 'innerGroup', new FormGroup({innerControl: new FormControl('', {nonNullable: true})})); c.contains('innerGroup'); c.setValue({innerGroup: {innerControl: ''}}); c.patchValue({}); @@ -358,7 +368,7 @@ describe('Typed Class', () => { }); it('supports nested explicit groups', () => { - const ig = new FormControl('', {initialValueIsDefault: true}); + const ig = new FormControl('', {nonNullable: true}); const og = new FormGroup({innerControl: ig}); const c = new FormGroup<{innerGroup: FormGroup<{innerControl: FormControl}>}>( {innerGroup: og}); @@ -379,7 +389,7 @@ describe('Typed Class', () => { it('supports groups with a single optional control', () => { const c = new FormGroup<{c?: FormControl}>({ - c: new FormControl('', {initialValueIsDefault: true}), + c: new FormControl('', {nonNullable: true}), }); { type ValueType = Partial<{c?: string}>; @@ -397,8 +407,8 @@ describe('Typed Class', () => { it('supports groups with mixed optional controls', () => { const c = new FormGroup<{c?: FormControl, d: FormControl}>({ - c: new FormControl('', {initialValueIsDefault: true}), - d: new FormControl('', {initialValueIsDefault: true}) + c: new FormControl('', {nonNullable: true}), + d: new FormControl('', {nonNullable: true}) }); { type ValueType = Partial<{c?: string, d: string}>; @@ -412,10 +422,10 @@ describe('Typed Class', () => { let t1 = c.getRawValue(); t1 = null as unknown as RawValueType; } - c.registerControl('c', new FormControl('', {initialValueIsDefault: true})); - c.addControl('c', new FormControl('', {initialValueIsDefault: true})); + c.registerControl('c', new FormControl('', {nonNullable: true})); + c.addControl('c', new FormControl('', {nonNullable: true})); c.removeControl('c'); - c.setControl('c', new FormControl('', {initialValueIsDefault: true})); + c.setControl('c', new FormControl('', {nonNullable: true})); c.contains('c'); c.setValue({c: '', d: ''}); c.patchValue({}); @@ -447,7 +457,7 @@ describe('Typed Class', () => { }); it('supports groups with inferred nested arrays', () => { - const arr = new FormArray([new FormControl('', {initialValueIsDefault: true})]); + const arr = new FormArray([new FormControl('', {nonNullable: true})]); const c = new FormGroup({a: arr}); { type ValueType = Partial<{a: Array}>; @@ -461,26 +471,26 @@ describe('Typed Class', () => { let t1 = c.getRawValue(); t1 = null as unknown as RawValueType; } - c.registerControl('a', new FormArray([ - new FormControl('', {initialValueIsDefault: true}), - new FormControl('', {initialValueIsDefault: true}) - ])); - c.registerControl('a', new FormArray([new FormControl('', {initialValueIsDefault: true})])); + c.registerControl( + 'a', new FormArray([ + new FormControl('', {nonNullable: true}), new FormControl('', {nonNullable: true}) + ])); + c.registerControl('a', new FormArray([new FormControl('', {nonNullable: true})])); // @ts-expect-error c.registerControl('a', new FormArray([])); c.registerControl('a', new FormArray>([])); - c.addControl('a', new FormArray([ - new FormControl('', {initialValueIsDefault: true}), - new FormControl('', {initialValueIsDefault: true}) - ])); - c.addControl('a', new FormArray([new FormControl('', {initialValueIsDefault: true})])); + c.addControl( + 'a', new FormArray([ + new FormControl('', {nonNullable: true}), new FormControl('', {nonNullable: true}) + ])); + c.addControl('a', new FormArray([new FormControl('', {nonNullable: true})])); // @ts-expect-error c.addControl('a', new FormArray([])); - c.setControl('a', new FormArray([ - new FormControl('', {initialValueIsDefault: true}), - new FormControl('', {initialValueIsDefault: true}) - ])); - c.setControl('a', new FormArray([new FormControl('', {initialValueIsDefault: true})])); + c.setControl( + 'a', new FormArray([ + new FormControl('', {nonNullable: true}), new FormControl('', {nonNullable: true}) + ])); + c.setControl('a', new FormArray([new FormControl('', {nonNullable: true})])); // @ts-expect-error c.setControl('a', new FormArray([])); c.contains('a'); @@ -494,8 +504,7 @@ describe('Typed Class', () => { }); it('supports groups with explicit nested arrays', () => { - const arr = - new FormArray>([new FormControl('', {initialValueIsDefault: true})]); + const arr = new FormArray>([new FormControl('', {nonNullable: true})]); const c = new FormGroup<{a: FormArray>}>({a: arr}); { type ValueType = Partial<{a: Array}>; @@ -524,9 +533,9 @@ describe('Typed Class', () => { [name: string]: FormControl; } const c = new FormGroup({ - returnIfFound: new FormControl('1234 Geary, San Francisco', {initialValueIsDefault: true}), - alex: new FormControl('999 Valencia, San Francisco', {initialValueIsDefault: true}), - andrew: new FormControl('100 Lombard, San Francisco', {initialValueIsDefault: true}) + returnIfFound: new FormControl('1234 Geary, San Francisco', {nonNullable: true}), + alex: new FormControl('999 Valencia, San Francisco', {nonNullable: true}), + andrew: new FormControl('100 Lombard, San Francisco', {nonNullable: true}) }); { type ValueType = Partial; @@ -542,26 +551,20 @@ describe('Typed Class', () => { } // Named fields. c.registerControl( - 'returnIfFound', - new FormControl('200 Ellis, San Francisco', {initialValueIsDefault: true})); + 'returnIfFound', new FormControl('200 Ellis, San Francisco', {nonNullable: true})); c.addControl( - 'returnIfFound', - new FormControl('200 Ellis, San Francisco', {initialValueIsDefault: true})); + 'returnIfFound', new FormControl('200 Ellis, San Francisco', {nonNullable: true})); c.setControl( - 'returnIfFound', - new FormControl('200 Ellis, San Francisco', {initialValueIsDefault: true})); + 'returnIfFound', new FormControl('200 Ellis, San Francisco', {nonNullable: true})); // c.removeControl('returnIfFound'); // Not allowed c.contains('returnIfFound'); c.setValue({returnIfFound: '200 Ellis, San Francisco', alex: '1 Main', andrew: '2 Main'}); c.patchValue({}); c.reset({returnIfFound: '200 Ellis, San Francisco'}); // Indexed fields. - c.registerControl( - 'igor', new FormControl('300 Page, San Francisco', {initialValueIsDefault: true})); - c.addControl( - 'igor', new FormControl('300 Page, San Francisco', {initialValueIsDefault: true})); - c.setControl( - 'igor', new FormControl('300 Page, San Francisco', {initialValueIsDefault: true})); + c.registerControl('igor', new FormControl('300 Page, San Francisco', {nonNullable: true})); + c.addControl('igor', new FormControl('300 Page, San Francisco', {nonNullable: true})); + c.setControl('igor', new FormControl('300 Page, San Francisco', {nonNullable: true})); c.contains('igor'); c.setValue({ returnIfFound: '200 Ellis, San Francisco', @@ -578,10 +581,10 @@ describe('Typed Class', () => { it('should have strongly-typed get', () => { const c = new FormGroup({ venue: new FormGroup({ - address: new FormControl('2200 Bryant', {initialValueIsDefault: true}), + address: new FormControl('2200 Bryant', {nonNullable: true}), date: new FormGroup({ - day: new FormControl(21, {initialValueIsDefault: true}), - month: new FormControl('March', {initialValueIsDefault: true}) + day: new FormControl(21, {nonNullable: true}), + month: new FormControl('March', {nonNullable: true}) }) }) }); @@ -616,7 +619,7 @@ describe('Typed Class', () => { it('is assignable to AbstractControl', () => { let ac: AbstractControl<{a?: boolean}>; - ac = new FormGroup({a: new FormControl(true, {initialValueIsDefault: true})}); + ac = new FormGroup({a: new FormControl(true, {nonNullable: true})}); }); it('is assignable to UntypedFormGroup', () => { @@ -639,7 +642,7 @@ describe('Typed Class', () => { describe('FormRecord', () => { it('supports inferred records', () => { - let c = new FormRecord({a: new FormControl(42, {initialValueIsDefault: true})}); + let c = new FormRecord({a: new FormControl(42, {nonNullable: true})}); { type ValueType = Partial<{[key: string]: number}>; let t: ValueType = c.value; @@ -652,9 +655,9 @@ describe('Typed Class', () => { let t1 = c.getRawValue(); t1 = null as unknown as RawValueType; } - c.registerControl('c', new FormControl(42, {initialValueIsDefault: true})); - c.addControl('c', new FormControl(42, {initialValueIsDefault: true})); - c.setControl('c', new FormControl(42, {initialValueIsDefault: true})); + c.registerControl('c', new FormControl(42, {nonNullable: true})); + c.addControl('c', new FormControl(42, {nonNullable: true})); + c.setControl('c', new FormControl(42, {nonNullable: true})); c.removeControl('c'); c.removeControl('missing'); c.contains('c'); @@ -665,8 +668,7 @@ describe('Typed Class', () => { }); it('supports explicit records', () => { - let c = new FormRecord>( - {a: new FormControl(42, {initialValueIsDefault: true})}); + let c = new FormRecord>({a: new FormControl(42, {nonNullable: true})}); { type ValueType = Partial<{[key: string]: number}>; let t: ValueType = c.value; @@ -679,9 +681,9 @@ describe('Typed Class', () => { let t1 = c.getRawValue(); t1 = null as unknown as RawValueType; } - c.registerControl('c', new FormControl(42, {initialValueIsDefault: true})); - c.addControl('c', new FormControl(42, {initialValueIsDefault: true})); - c.setControl('c', new FormControl(42, {initialValueIsDefault: true})); + c.registerControl('c', new FormControl(42, {nonNullable: true})); + c.addControl('c', new FormControl(42, {nonNullable: true})); + c.setControl('c', new FormControl(42, {nonNullable: true})); c.contains('c'); c.contains('foo'); c.setValue({a: 42, c: 0}); @@ -693,7 +695,7 @@ describe('Typed Class', () => { describe('FormArray', () => { it('supports inferred arrays', () => { - const c = new FormArray([new FormControl('', {initialValueIsDefault: true})]); + const c = new FormArray([new FormControl('', {nonNullable: true})]); { type ValueType = string[]; let t: ValueType = c.value; @@ -701,10 +703,10 @@ describe('Typed Class', () => { t1 = null as unknown as ValueType; } c.at(0); - c.push(new FormControl('', {initialValueIsDefault: true})); - c.insert(0, new FormControl('', {initialValueIsDefault: true})); + c.push(new FormControl('', {nonNullable: true})); + c.insert(0, new FormControl('', {nonNullable: true})); c.removeAt(0); - c.setControl(0, new FormControl('', {initialValueIsDefault: true})); + c.setControl(0, new FormControl('', {nonNullable: true})); c.setValue(['', '']); c.patchValue([]); c.patchValue(['']); @@ -716,8 +718,7 @@ describe('Typed Class', () => { }); it('supports explicit arrays', () => { - const c = - new FormArray>([new FormControl('', {initialValueIsDefault: true})]); + const c = new FormArray>([new FormControl('', {nonNullable: true})]); { type ValueType = string[]; let t: ValueType = c.value; @@ -727,15 +728,15 @@ describe('Typed Class', () => { }); it('supports explicit arrays with boolean types', () => { - const c0 = new FormArray([new FormControl(true, {initialValueIsDefault: true})]); + const c0 = new FormArray([new FormControl(true, {nonNullable: true})]); const c1: AbstractControl = - new FormArray([new FormControl(true, {initialValueIsDefault: true})]); + new FormArray([new FormControl(true, {nonNullable: true})]); }); it('supports arrays with the default type', () => { let c: FormArray; - c = new FormArray([new FormControl('', {initialValueIsDefault: true})]); + c = new FormArray([new FormControl('', {nonNullable: true})]); { type ValueType = any[]; let t: ValueType = c.value; @@ -744,10 +745,10 @@ describe('Typed Class', () => { } c.at(0); c.at(0).valueChanges.subscribe(v => {}); - c.push(new FormControl('', {initialValueIsDefault: true})); - c.insert(0, new FormControl('', {initialValueIsDefault: true})); + c.push(new FormControl('', {nonNullable: true})); + c.insert(0, new FormControl('', {nonNullable: true})); c.removeAt(0); - c.setControl(0, new FormControl('', {initialValueIsDefault: true})); + c.setControl(0, new FormControl('', {nonNullable: true})); c.setValue(['', '']); c.patchValue([]); c.patchValue(['']); @@ -783,8 +784,7 @@ describe('Typed Class', () => { }); it('supports inferred nested arrays', () => { - const c = - new FormArray([new FormArray([new FormControl('', {initialValueIsDefault: true})])]); + const c = new FormArray([new FormArray([new FormControl('', {nonNullable: true})])]); { type ValueType = Array>; let t: ValueType = c.value; @@ -795,7 +795,7 @@ describe('Typed Class', () => { it('supports explicit nested arrays', () => { const c = new FormArray>>( - [new FormArray([new FormControl('', {initialValueIsDefault: true})])]); + [new FormArray([new FormControl('', {nonNullable: true})])]); { type ValueType = Array>; let t: ValueType = c.value; @@ -805,7 +805,7 @@ describe('Typed Class', () => { }); it('supports arrays with inferred nested groups', () => { - const fg = new FormGroup({c: new FormControl('', {initialValueIsDefault: true})}); + const fg = new FormGroup({c: new FormControl('', {nonNullable: true})}); const c = new FormArray([fg]); { type ValueType = Array>; @@ -822,8 +822,8 @@ describe('Typed Class', () => { }); it('supports arrays with explicit nested groups', () => { - const fg = new FormGroup<{c: FormControl}>( - {c: new FormControl('', {initialValueIsDefault: true})}); + const fg = + new FormGroup<{c: FormControl}>({c: new FormControl('', {nonNullable: true})}); const c = new FormArray}>>([fg]); { type ValueType = Array>; @@ -842,7 +842,7 @@ describe('Typed Class', () => { it('should have strongly-typed get', () => { const c = new FormGroup({ food: new FormArray([ - new FormControl('2200 Bryant', {initialValueIsDefault: true}), + new FormControl('2200 Bryant', {nonNullable: true}), ]) }); const rv = c.getRawValue(); @@ -874,32 +874,32 @@ describe('Typed Class', () => { } const myParty = new FormGroup({ venue: new FormGroup({ - location: new FormControl('San Francisco', {initialValueIsDefault: true}), + location: new FormControl('San Francisco', {nonNullable: true}), date: new FormGroup({ - year: new FormControl(2022, {initialValueIsDefault: true}), - month: new FormControl('May', {initialValueIsDefault: true}), - day: new FormControl(1, {initialValueIsDefault: true}), + year: new FormControl(2022, {nonNullable: true}), + month: new FormControl('May', {nonNullable: true}), + day: new FormControl(1, {nonNullable: true}), }), }), dinnerOptions: new FormArray([ new FormGroup({ food: new FormGroup({ - entree: new FormControl('Baked Tofu', {initialValueIsDefault: true}), - dessert: new FormControl('Cheesecake', {initialValueIsDefault: true}), + entree: new FormControl('Baked Tofu', {nonNullable: true}), + dessert: new FormControl('Cheesecake', {nonNullable: true}), }), price: new FormGroup({ - amount: new FormControl(10, {initialValueIsDefault: true}), - currency: new FormControl('USD', {initialValueIsDefault: true}), + amount: new FormControl(10, {nonNullable: true}), + currency: new FormControl('USD', {nonNullable: true}), }), }), new FormGroup({ food: new FormGroup({ - entree: new FormControl('Eggplant Parm', {initialValueIsDefault: true}), - dessert: new FormControl('Chocolate Mousse', {initialValueIsDefault: true}), + entree: new FormControl('Eggplant Parm', {nonNullable: true}), + dessert: new FormControl('Chocolate Mousse', {nonNullable: true}), }), price: new FormGroup({ - amount: new FormControl(12, {initialValueIsDefault: true}), - currency: new FormControl('USD', {initialValueIsDefault: true}), + amount: new FormControl(12, {nonNullable: true}), + currency: new FormControl('USD', {nonNullable: true}), }), }) ]) @@ -991,7 +991,7 @@ describe('Typed Class', () => { }); it('non-nullably from values', () => { - const c = fb.control('foo', {initialValueIsDefault: true}); + const c = fb.control('foo', {nonNullable: true}); { type RawValueType = string; let t: RawValueType = c.getRawValue(); @@ -1011,7 +1011,7 @@ describe('Typed Class', () => { }); it('non-nullably from FormStates', () => { - const c = fb.control({value: 'foo', disabled: false}, {initialValueIsDefault: true}); + const c = fb.control({value: 'foo', disabled: false}, {nonNullable: true}); { type RawValueType = string; let t: RawValueType = c.getRawValue(); @@ -1095,7 +1095,7 @@ describe('Typed Class', () => { }); it('non-nullably', () => { - const c = fb.group({foo: new FormControl('bar', {initialValueIsDefault: true})}); + const c = fb.group({foo: new FormControl('bar', {nonNullable: true})}); { type ControlsType = {foo: FormControl}; let t: ControlsType = c.controls; @@ -1179,7 +1179,7 @@ describe('Typed Class', () => { }); it('non-nullably', () => { - const c = fb.array([new FormControl('foo', {initialValueIsDefault: true})]); + const c = fb.array([new FormControl('foo', {nonNullable: true})]); { type ControlsType = Array>; let t: ControlsType = c.controls; @@ -1237,7 +1237,7 @@ describe('Typed Class', () => { dessert: 'also Souffle', }), price: fb.group({ - amount: new FormControl(50, {initialValueIsDefault: true}), + amount: new FormControl(50, {nonNullable: true}), currency: 'USD', }) })]) @@ -1375,7 +1375,7 @@ describe('Typed Class', () => { t1 = null as unknown as ControlsType; } let fc = c.controls.foo; - fc = new FormControl('', {initialValueIsDefault: true}); + fc = new FormControl('', {nonNullable: true}); }); describe('from objects with FormControls', () => {