diff --git a/packages/forms/src/directives/abstract_control_directive.ts b/packages/forms/src/directives/abstract_control_directive.ts index fe0911ec344..6459ff2e69e 100644 --- a/packages/forms/src/directives/abstract_control_directive.ts +++ b/packages/forms/src/directives/abstract_control_directive.ts @@ -264,7 +264,7 @@ export abstract class AbstractControlDirective { * Resets the control with the provided value if the control is present. */ reset(value: any = undefined): void { - if (this.control) this.control.reset(value); + this.control?.reset(value); } /** diff --git a/packages/forms/src/directives/abstract_form_group_directive.ts b/packages/forms/src/directives/abstract_form_group_directive.ts index b1ad624edb7..f434e264a33 100644 --- a/packages/forms/src/directives/abstract_form_group_directive.ts +++ b/packages/forms/src/directives/abstract_form_group_directive.ts @@ -41,10 +41,8 @@ export class AbstractFormGroupDirective extends ControlContainer implements OnIn /** @docs-private */ ngOnDestroy(): void { - if (this.formDirective) { - // Remove the group from its parent group. - this.formDirective.removeFormGroup(this); - } + // Remove the group from its parent group. + this.formDirective?.removeFormGroup(this); } /** diff --git a/packages/forms/src/directives/ng_form.ts b/packages/forms/src/directives/ng_form.ts index 6584fe343cc..6a67dda944c 100644 --- a/packages/forms/src/directives/ng_form.ts +++ b/packages/forms/src/directives/ng_form.ts @@ -256,9 +256,9 @@ export class NgForm extends ControlContainer implements Form, AfterViewInit { removeControl(dir: NgModel): void { resolvedPromise.then(() => { const container = this._findContainer(dir.path); - if (container) { - container.removeControl(dir.name); - } + + container?.removeControl(dir.name); + this._directives.delete(dir); }); } @@ -288,9 +288,7 @@ export class NgForm extends ControlContainer implements Form, AfterViewInit { removeFormGroup(dir: NgModelGroup): void { resolvedPromise.then(() => { const container = this._findContainer(dir.path); - if (container) { - container.removeControl(dir.name); - } + container?.removeControl?.(dir.name); }); } diff --git a/packages/forms/src/directives/ng_model.ts b/packages/forms/src/directives/ng_model.ts index 344865fed05..51f8bd9e009 100644 --- a/packages/forms/src/directives/ng_model.ts +++ b/packages/forms/src/directives/ng_model.ts @@ -278,7 +278,7 @@ export class NgModel extends NgControl implements OnChanges, OnDestroy { /** @docs-private */ ngOnDestroy(): void { - this.formDirective && this.formDirective.removeControl(this); + this.formDirective?.removeControl(this); } /** diff --git a/packages/forms/src/directives/reactive_directives/abstract_form.directive.ts b/packages/forms/src/directives/reactive_directives/abstract_form.directive.ts index b90e7d20c4e..407d7475c3d 100644 --- a/packages/forms/src/directives/reactive_directives/abstract_form.directive.ts +++ b/packages/forms/src/directives/reactive_directives/abstract_form.directive.ts @@ -357,24 +357,20 @@ export abstract class AbstractFormDirective } private _cleanUpFormContainer(dir: FormArrayName | FormGroupName): void { - if (this.form) { - const ctrl: any = this.form.get(dir.path); - if (ctrl) { - const isControlUpdated = cleanUpFormContainer(ctrl, dir); - if (isControlUpdated) { - // Run validity check only in case a control was updated (i.e. view validators were - // removed) as removing view validators might cause validity to change. - ctrl.updateValueAndValidity({emitEvent: false}); - } + const ctrl: any = this.form?.get(dir.path); + if (ctrl) { + const isControlUpdated = cleanUpFormContainer(ctrl, dir); + if (isControlUpdated) { + // Run validity check only in case a control was updated (i.e. view validators were + // removed) as removing view validators might cause validity to change. + ctrl.updateValueAndValidity({emitEvent: false}); } } } private _updateRegistrations() { this.form._registerOnCollectionChange(this._onCollectionChange); - if (this._oldForm) { - this._oldForm._registerOnCollectionChange(() => {}); - } + this._oldForm?._registerOnCollectionChange(() => {}); } private _updateValidators() { diff --git a/packages/forms/src/directives/reactive_directives/form_control_name.ts b/packages/forms/src/directives/reactive_directives/form_control_name.ts index 19f97c76c79..17b05b7ed39 100644 --- a/packages/forms/src/directives/reactive_directives/form_control_name.ts +++ b/packages/forms/src/directives/reactive_directives/form_control_name.ts @@ -179,9 +179,7 @@ export class FormControlName extends NgControl implements OnChanges, OnDestroy { /** @docs-private */ ngOnDestroy(): void { - if (this.formDirective) { - this.formDirective.removeControl(this); - } + this.formDirective?.removeControl(this); } /** diff --git a/packages/forms/src/directives/select_control_value_accessor.ts b/packages/forms/src/directives/select_control_value_accessor.ts index 80f38b1633c..085bac2191c 100644 --- a/packages/forms/src/directives/select_control_value_accessor.ts +++ b/packages/forms/src/directives/select_control_value_accessor.ts @@ -286,7 +286,7 @@ export class NgSelectOption implements OnDestroy { @Input('value') set value(value: any) { this._setElementValue(value); - if (this._select) this._select._writeValueAfterRender(); + this._select?._writeValueAfterRender(); } /** @internal */ @@ -296,9 +296,7 @@ export class NgSelectOption implements OnDestroy { /** @docs-private */ ngOnDestroy(): void { - if (this._select) { - this._select._optionMap.delete(this.id); - this._select._writeValueAfterRender(); - } + this._select?._optionMap.delete(this.id); + this._select?._writeValueAfterRender(); } } diff --git a/packages/forms/src/directives/shared.ts b/packages/forms/src/directives/shared.ts index 57b9601372e..85abf8e20ae 100644 --- a/packages/forms/src/directives/shared.ts +++ b/packages/forms/src/directives/shared.ts @@ -120,10 +120,9 @@ export function cleanUpControl( // case. We still check the presence of `valueAccessor` before invoking its methods to make sure // that cleanup works correctly if app code or tests are setup to ignore the error thrown from // `selectValueAccessor`. See https://github.com/angular/angular/issues/40521. - if (dir.valueAccessor) { - dir.valueAccessor.registerOnChange(noop); - dir.valueAccessor.registerOnTouched(noop); - } + + dir?.valueAccessor?.registerOnChange(noop); + dir?.valueAccessor?.registerOnTouched(noop); cleanUpValidators(control, dir); diff --git a/packages/forms/src/directives/validators.ts b/packages/forms/src/directives/validators.ts index 1e70b378f47..9f1cc2309c1 100644 --- a/packages/forms/src/directives/validators.ts +++ b/packages/forms/src/directives/validators.ts @@ -162,9 +162,7 @@ abstract class AbstractValidatorDirective implements Validator, OnChanges { const input = this.normalizeInput(changes[this.inputName].currentValue); this._enabled = this.enabled(input); this._validator = this._enabled ? this.createValidator(input) : nullValidator; - if (this._onChange) { - this._onChange(); - } + this._onChange?.(); } } diff --git a/packages/forms/src/model/abstract_model.ts b/packages/forms/src/model/abstract_model.ts index ad17b3fd42b..31b48db88f6 100644 --- a/packages/forms/src/model/abstract_model.ts +++ b/packages/forms/src/model/abstract_model.ts @@ -997,8 +997,8 @@ export abstract class AbstractControl< this.touched = true; const sourceControl = opts.sourceControl ?? this; - if (this._parent && !opts.onlySelf) { - this._parent.markAsTouched({...opts, sourceControl}); + if (!opts.onlySelf) { + this._parent?.markAsTouched({...opts, sourceControl}); } if (changed && opts.emitEvent !== false) { @@ -1087,8 +1087,8 @@ export abstract class AbstractControl< control.markAsUntouched({onlySelf: true, emitEvent: opts.emitEvent, sourceControl}); }); - if (this._parent && !opts.onlySelf) { - this._parent._updateTouched(opts, sourceControl); + if (!opts.onlySelf) { + this._parent?._updateTouched(opts, sourceControl); } if (changed && opts.emitEvent !== false) { @@ -1131,8 +1131,8 @@ export abstract class AbstractControl< this.pristine = false; const sourceControl = opts.sourceControl ?? this; - if (this._parent && !opts.onlySelf) { - this._parent.markAsDirty({...opts, sourceControl}); + if (!opts.onlySelf) { + this._parent?.markAsDirty({...opts, sourceControl}); } if (changed && opts.emitEvent !== false) { @@ -1184,8 +1184,8 @@ export abstract class AbstractControl< control.markAsPristine({onlySelf: true, emitEvent: opts.emitEvent}); }); - if (this._parent && !opts.onlySelf) { - this._parent._updatePristine(opts, sourceControl); + if (!opts.onlySelf) { + this._parent?._updatePristine(opts, sourceControl); } if (changed && opts.emitEvent !== false) { @@ -1230,8 +1230,8 @@ export abstract class AbstractControl< (this.statusChanges as EventEmitter).emit(this.status); } - if (this._parent && !opts.onlySelf) { - this._parent.markAsPending({...opts, sourceControl}); + if (!opts.onlySelf) { + this._parent?.markAsPending({...opts, sourceControl}); } } @@ -1321,12 +1321,12 @@ export abstract class AbstractControl< opts: {onlySelf?: boolean; emitEvent?: boolean; skipPristineCheck?: boolean}, sourceControl: AbstractControl, ): void { - if (this._parent && !opts.onlySelf) { - this._parent.updateValueAndValidity(opts); + if (!opts.onlySelf) { + this._parent?.updateValueAndValidity(opts); if (!opts.skipPristineCheck) { - this._parent._updatePristine({}, sourceControl); + this._parent?._updatePristine({}, sourceControl); } - this._parent._updateTouched({}, sourceControl); + this._parent?._updateTouched({}, sourceControl); } } @@ -1415,8 +1415,8 @@ export abstract class AbstractControl< (this.statusChanges as EventEmitter).emit(this.status); } - if (this._parent && !opts.onlySelf) { - this._parent.updateValueAndValidity({...opts, sourceControl}); + if (!opts.onlySelf) { + this._parent?.updateValueAndValidity({...opts, sourceControl}); } } @@ -1604,7 +1604,7 @@ export abstract class AbstractControl< */ getError(errorCode: string, path?: Array | string): any { const control = path ? this.get(path) : this; - return control && control.errors ? control.errors[errorCode] : null; + return control?.errors ? control.errors[errorCode] : null; } /** @@ -1729,8 +1729,8 @@ export abstract class AbstractControl< const changed = this.pristine !== newPristine; this.pristine = newPristine; - if (this._parent && !opts.onlySelf) { - this._parent._updatePristine(opts, changedControl); + if (!opts.onlySelf) { + this._parent?._updatePristine(opts, changedControl); } if (changed) { @@ -1743,8 +1743,8 @@ export abstract class AbstractControl< this.touched = this._anyControlsTouched(); this._events.next(new TouchedChangeEvent(this.touched, changedControl)); - if (this._parent && !opts.onlySelf) { - this._parent._updateTouched(opts, changedControl); + if (!opts.onlySelf) { + this._parent?._updateTouched(opts, changedControl); } } @@ -1768,8 +1768,7 @@ export abstract class AbstractControl< * @internal */ private _parentMarkedDirty(onlySelf?: boolean): boolean { - const parentDirty = this._parent && this._parent.dirty; - return !onlySelf && !!parentDirty && !this._parent!._anyControlsDirty(); + return !onlySelf && !!this._parent?.dirty && !this._parent!._anyControlsDirty(); } /** @internal */