diff --git a/packages/core/test/bundling/forms/bundle.golden_symbols.json b/packages/core/test/bundling/forms/bundle.golden_symbols.json
index 53a49c913c..037046f00d 100644
--- a/packages/core/test/bundling/forms/bundle.golden_symbols.json
+++ b/packages/core/test/bundling/forms/bundle.golden_symbols.json
@@ -221,15 +221,6 @@
{
"name": "FormControlName"
},
- {
- "name": "FormErrorExamples_formControlName"
- },
- {
- "name": "FormErrorExamples_formGroupName"
- },
- {
- "name": "FormErrorExamples_ngModelGroup"
- },
{
"name": "FormGroup"
},
@@ -497,9 +488,6 @@
{
"name": "RangeValueAccessor"
},
- {
- "name": "ReactiveErrors"
- },
{
"name": "ReactiveFormsComponent"
},
@@ -608,9 +596,6 @@
{
"name": "TRANSITION_ID"
},
- {
- "name": "TemplateDrivenErrors"
- },
{
"name": "TemplateFormsComponent"
},
@@ -701,9 +686,6 @@
{
"name": "_keyMap"
},
- {
- "name": "_noControlError"
- },
{
"name": "_randomChar"
},
@@ -716,9 +698,6 @@
{
"name": "_testabilityGetter"
},
- {
- "name": "_throwError"
- },
{
"name": "addComponentLogic"
},
@@ -1628,9 +1607,6 @@
{
"name": "u"
},
- {
- "name": "unimplemented"
- },
{
"name": "unwrapRNode"
},
diff --git a/packages/forms/src/directives/ng_control.ts b/packages/forms/src/directives/ng_control.ts
index 95fe13f589..23cb4edfd0 100644
--- a/packages/forms/src/directives/ng_control.ts
+++ b/packages/forms/src/directives/ng_control.ts
@@ -13,7 +13,9 @@ import {ControlValueAccessor} from './control_value_accessor';
import {AsyncValidator, AsyncValidatorFn, Validator, ValidatorFn} from './validators';
function unimplemented(): any {
- throw new Error('unimplemented');
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
+ throw new Error('unimplemented');
+ }
}
/**
diff --git a/packages/forms/src/directives/ng_model.ts b/packages/forms/src/directives/ng_model.ts
index cc115be32e..73a1ac6ae5 100644
--- a/packages/forms/src/directives/ng_model.ts
+++ b/packages/forms/src/directives/ng_model.ts
@@ -317,18 +317,20 @@ export class NgModel extends NgControl implements OnChanges, OnDestroy {
}
private _checkParentType(): void {
- if (!(this._parent instanceof NgModelGroup) &&
- this._parent instanceof AbstractFormGroupDirective) {
- TemplateDrivenErrors.formGroupNameException();
- } else if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) {
- TemplateDrivenErrors.modelParentException();
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
+ if (!(this._parent instanceof NgModelGroup) &&
+ this._parent instanceof AbstractFormGroupDirective) {
+ TemplateDrivenErrors.formGroupNameException();
+ } else if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) {
+ TemplateDrivenErrors.modelParentException();
+ }
}
}
private _checkName(): void {
if (this.options && this.options.name) this.name = this.options.name;
- if (!this._isStandalone() && !this.name) {
+ if (!this._isStandalone() && !this.name && (typeof ngDevMode === 'undefined' || ngDevMode)) {
TemplateDrivenErrors.missingNameException();
}
}
diff --git a/packages/forms/src/directives/ng_model_group.ts b/packages/forms/src/directives/ng_model_group.ts
index d5995df8a7..7baabdf9cc 100644
--- a/packages/forms/src/directives/ng_model_group.ts
+++ b/packages/forms/src/directives/ng_model_group.ts
@@ -68,7 +68,8 @@ export class NgModelGroup extends AbstractFormGroupDirective implements OnInit,
/** @internal */
_checkParentType(): void {
- if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm)) {
+ if (!(this._parent instanceof NgModelGroup) && !(this._parent instanceof NgForm) &&
+ (typeof ngDevMode === 'undefined' || ngDevMode)) {
TemplateDrivenErrors.modelGroupParentException();
}
}
diff --git a/packages/forms/src/directives/radio_control_value_accessor.ts b/packages/forms/src/directives/radio_control_value_accessor.ts
index 4de1274f2d..50fbee6e67 100644
--- a/packages/forms/src/directives/radio_control_value_accessor.ts
+++ b/packages/forms/src/directives/radio_control_value_accessor.ts
@@ -17,6 +17,13 @@ export const RADIO_VALUE_ACCESSOR: any = {
multi: true
};
+function throwNameError() {
+ throw new Error(`
+ If you define both a name and a formControlName attribute on your radio button, their values
+ must match. Ex:
+ `);
+}
+
/**
* @description
* Class used by Angular to track radio buttons. For internal use only.
@@ -213,16 +220,10 @@ export class RadioControlValueAccessor implements ControlValueAccessor, OnDestro
}
private _checkName(): void {
- if (this.name && this.formControlName && this.name !== this.formControlName) {
- this._throwNameError();
+ if (this.name && this.formControlName && this.name !== this.formControlName &&
+ (typeof ngDevMode === 'undefined' || ngDevMode)) {
+ throwNameError();
}
if (!this.name && this.formControlName) this.name = this.formControlName;
}
-
- private _throwNameError(): void {
- throw new Error(`
- If you define both a name and a formControlName attribute on your radio button, their values
- must match. Ex:
- `);
- }
}
diff --git a/packages/forms/src/directives/reactive_directives/form_control_directive.ts b/packages/forms/src/directives/reactive_directives/form_control_directive.ts
index 2f288fbe3c..7d496aa99b 100644
--- a/packages/forms/src/directives/reactive_directives/form_control_directive.ts
+++ b/packages/forms/src/directives/reactive_directives/form_control_directive.ts
@@ -68,11 +68,13 @@ export class FormControlDirective extends NgControl implements OnChanges {
/**
* @description
- * Triggers a warning that this input should not be used with reactive forms.
+ * Triggers a warning in dev mode that this input should not be used with reactive forms.
*/
@Input('disabled')
set isDisabled(isDisabled: boolean) {
- ReactiveErrors.disabledAttrWarning();
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
+ ReactiveErrors.disabledAttrWarning();
+ }
}
// TODO(kara): remove next 4 properties once deprecation period is over
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 0802ff2b0e..34311c1886 100644
--- a/packages/forms/src/directives/reactive_directives/form_control_name.ts
+++ b/packages/forms/src/directives/reactive_directives/form_control_name.ts
@@ -92,11 +92,13 @@ export class FormControlName extends NgControl implements OnChanges, OnDestroy {
/**
* @description
- * Triggers a warning that this input should not be used with reactive forms.
+ * Triggers a warning in dev mode that this input should not be used with reactive forms.
*/
@Input('disabled')
set isDisabled(isDisabled: boolean) {
- ReactiveErrors.disabledAttrWarning();
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
+ ReactiveErrors.disabledAttrWarning();
+ }
}
// TODO(kara): remove next 4 properties once deprecation period is over
@@ -212,13 +214,16 @@ export class FormControlName extends NgControl implements OnChanges, OnDestroy {
}
private _checkParentType(): void {
- if (!(this._parent instanceof FormGroupName) &&
- this._parent instanceof AbstractFormGroupDirective) {
- ReactiveErrors.ngModelGroupException();
- } else if (
- !(this._parent instanceof FormGroupName) && !(this._parent instanceof FormGroupDirective) &&
- !(this._parent instanceof FormArrayName)) {
- ReactiveErrors.controlParentException();
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
+ if (!(this._parent instanceof FormGroupName) &&
+ this._parent instanceof AbstractFormGroupDirective) {
+ ReactiveErrors.ngModelGroupException();
+ } else if (
+ !(this._parent instanceof FormGroupName) &&
+ !(this._parent instanceof FormGroupDirective) &&
+ !(this._parent instanceof FormArrayName)) {
+ ReactiveErrors.controlParentException();
+ }
}
}
diff --git a/packages/forms/src/directives/reactive_directives/form_group_directive.ts b/packages/forms/src/directives/reactive_directives/form_group_directive.ts
index f6ef709f55..3f864fc7c7 100644
--- a/packages/forms/src/directives/reactive_directives/form_group_directive.ts
+++ b/packages/forms/src/directives/reactive_directives/form_group_directive.ts
@@ -291,7 +291,7 @@ export class FormGroupDirective extends ControlContainer implements Form, OnChan
}
private _checkFormPresent() {
- if (!this.form) {
+ if (!this.form && (typeof ngDevMode === 'undefined' || ngDevMode)) {
ReactiveErrors.missingFormException();
}
}
diff --git a/packages/forms/src/directives/reactive_directives/form_group_name.ts b/packages/forms/src/directives/reactive_directives/form_group_name.ts
index 6a3aa99ba5..5cd1bf4ff6 100644
--- a/packages/forms/src/directives/reactive_directives/form_group_name.ts
+++ b/packages/forms/src/directives/reactive_directives/form_group_name.ts
@@ -96,7 +96,7 @@ export class FormGroupName extends AbstractFormGroupDirective implements OnInit,
/** @internal */
_checkParentType(): void {
- if (_hasInvalidParent(this._parent)) {
+ if (_hasInvalidParent(this._parent) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
ReactiveErrors.groupParentException();
}
}
@@ -228,7 +228,7 @@ export class FormArrayName extends ControlContainer implements OnInit, OnDestroy
}
private _checkParentType(): void {
- if (_hasInvalidParent(this._parent)) {
+ if (_hasInvalidParent(this._parent) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
ReactiveErrors.arrayParentException();
}
}
diff --git a/packages/forms/src/directives/reactive_errors.ts b/packages/forms/src/directives/reactive_errors.ts
index 835f358aa6..0d32b3e76e 100644
--- a/packages/forms/src/directives/reactive_errors.ts
+++ b/packages/forms/src/directives/reactive_errors.ts
@@ -33,6 +33,7 @@ export class ReactiveErrors {
${Examples.ngModelGroup}`);
}
+
static missingFormException(): void {
throw new Error(`formGroup expects a FormGroup instance. Please pass one in.
diff --git a/packages/forms/src/directives/select_control_value_accessor.ts b/packages/forms/src/directives/select_control_value_accessor.ts
index 4e2832c2a5..b333b0d0ca 100644
--- a/packages/forms/src/directives/select_control_value_accessor.ts
+++ b/packages/forms/src/directives/select_control_value_accessor.ts
@@ -115,7 +115,7 @@ export class SelectControlValueAccessor implements ControlValueAccessor {
*/
@Input()
set compareWith(fn: (o1: any, o2: any) => boolean) {
- if (typeof fn !== 'function') {
+ if (typeof fn !== 'function' && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`);
}
this._compareWith = fn;
diff --git a/packages/forms/src/directives/select_multiple_control_value_accessor.ts b/packages/forms/src/directives/select_multiple_control_value_accessor.ts
index ebee781504..2d6378fa04 100644
--- a/packages/forms/src/directives/select_multiple_control_value_accessor.ts
+++ b/packages/forms/src/directives/select_multiple_control_value_accessor.ts
@@ -112,7 +112,7 @@ export class SelectMultipleControlValueAccessor implements ControlValueAccessor
*/
@Input()
set compareWith(fn: (o1: any, o2: any) => boolean) {
- if (typeof fn !== 'function') {
+ if (typeof fn !== 'function' && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw new Error(`compareWith must be a function, but received ${JSON.stringify(fn)}`);
}
this._compareWith = fn;
diff --git a/packages/forms/src/directives/shared.ts b/packages/forms/src/directives/shared.ts
index 04c950aa9f..a3dcce5616 100644
--- a/packages/forms/src/directives/shared.ts
+++ b/packages/forms/src/directives/shared.ts
@@ -33,8 +33,10 @@ export function controlPath(name: string|null, parent: ControlContainer): string
}
export function setUpControl(control: FormControl, dir: NgControl): void {
- if (!control) _throwError(dir, 'Cannot find control with');
- if (!dir.valueAccessor) _throwError(dir, 'No value accessor for form control with');
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
+ if (!control) _throwError(dir, 'Cannot find control with');
+ if (!dir.valueAccessor) _throwError(dir, 'No value accessor for form control with');
+ }
control.validator = Validators.compose([control.validator!, dir.validator]);
control.asyncValidator = Validators.composeAsync([control.asyncValidator!, dir.asyncValidator]);
@@ -64,8 +66,14 @@ export function setUpControl(control: FormControl, dir: NgControl): void {
}
export function cleanUpControl(control: FormControl, dir: NgControl) {
- dir.valueAccessor!.registerOnChange(() => _noControlError(dir));
- dir.valueAccessor!.registerOnTouched(() => _noControlError(dir));
+ const noop = () => {
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
+ _noControlError(dir);
+ }
+ };
+
+ dir.valueAccessor!.registerOnChange(noop);
+ dir.valueAccessor!.registerOnTouched(noop);
dir._rawValidators.forEach((validator: any) => {
if (validator.registerOnValidatorChange) {
@@ -120,7 +128,8 @@ function setUpModelChangePipeline(control: FormControl, dir: NgControl): void {
export function setUpFormContainer(
control: FormGroup|FormArray, dir: AbstractFormGroupDirective|FormArrayName) {
- if (control == null) _throwError(dir, 'Cannot find control with');
+ if (control == null && (typeof ngDevMode === 'undefined' || ngDevMode))
+ _throwError(dir, 'Cannot find control with');
control.validator = Validators.compose([control.validator, dir.validator]);
control.asyncValidator = Validators.composeAsync([control.asyncValidator, dir.asyncValidator]);
}
@@ -190,7 +199,7 @@ export function selectValueAccessor(
dir: NgControl, valueAccessors: ControlValueAccessor[]): ControlValueAccessor|null {
if (!valueAccessors) return null;
- if (!Array.isArray(valueAccessors))
+ if (!Array.isArray(valueAccessors) && (typeof ngDevMode === 'undefined' || ngDevMode))
_throwError(dir, 'Value accessor was not provided as an array for form control with');
let defaultAccessor: ControlValueAccessor|undefined = undefined;
@@ -202,12 +211,12 @@ export function selectValueAccessor(
defaultAccessor = v;
} else if (isBuiltInAccessor(v)) {
- if (builtinAccessor)
+ if (builtinAccessor && (typeof ngDevMode === 'undefined' || ngDevMode))
_throwError(dir, 'More than one built-in value accessor matches form control with');
builtinAccessor = v;
} else {
- if (customAccessor)
+ if (customAccessor && (typeof ngDevMode === 'undefined' || ngDevMode))
_throwError(dir, 'More than one custom value accessor matches form control with');
customAccessor = v;
}
@@ -217,7 +226,9 @@ export function selectValueAccessor(
if (builtinAccessor) return builtinAccessor;
if (defaultAccessor) return defaultAccessor;
- _throwError(dir, 'No valid value accessor for form control with');
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
+ _throwError(dir, 'No valid value accessor for form control with');
+ }
return null;
}
@@ -234,7 +245,9 @@ export function _ngModelWarning(
if (((warningConfig === null || warningConfig === 'once') && !type._ngModelWarningSentOnce) ||
(warningConfig === 'always' && !instance._ngModelWarningSent)) {
- ReactiveErrors.ngModelWarning(name);
+ if (typeof ngDevMode === 'undefined' || ngDevMode) {
+ ReactiveErrors.ngModelWarning(name);
+ }
type._ngModelWarningSentOnce = true;
instance._ngModelWarningSent = true;
}
diff --git a/packages/forms/src/validators.ts b/packages/forms/src/validators.ts
index d2fb2bbf86..d45286a370 100644
--- a/packages/forms/src/validators.ts
+++ b/packages/forms/src/validators.ts
@@ -469,7 +469,7 @@ function isPresent(o: any): boolean {
export function toObservable(r: any): Observable {
const obs = isPromise(r) ? from(r) : r;
- if (!(isObservable(obs))) {
+ if (!(isObservable(obs)) && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw new Error(`Expected validator to return Promise or Observable.`);
}
return obs;