Skip to content

Commit

Permalink
fix(forms): improve error message for invalid value accessors
Browse files Browse the repository at this point in the history
  • Loading branch information
ameryousuf committed Feb 24, 2022
1 parent bad5096 commit 7e15ca1
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 5 deletions.
12 changes: 8 additions & 4 deletions packages/forms/src/directives/shared.ts
Original file line number Diff line number Diff line change
Expand Up @@ -272,16 +272,18 @@ function _noControlError(dir: NgControl) {
return _throwError(dir, 'There is no FormControl instance attached to form control element with');
}

function _throwError(dir: AbstractControlDirective, message: string): void {
function _throwError(dir: AbstractControlDirective, message: string, extraMessage?: string): void {
let messageEnd: string;
if (dir.path!.length > 1) {
messageEnd = `path: '${dir.path!.join(' -> ')}'`;
} else if (dir.path![0]) {
messageEnd = `name: '${dir.path}'`;
} else {
messageEnd = 'unspecified name attribute';
messageEnd = 'unspecified name attribute.';
}
throw new Error(`${message} ${messageEnd}`);

extraMessage = extraMessage ? '\n' + extraMessage : '';
throw new Error(`${message} ${messageEnd}${extraMessage}`);
}

export function isPropertyUpdated(changes: {[key: string]: any}, viewModel: any): boolean {
Expand Down Expand Up @@ -315,7 +317,9 @@ export function selectValueAccessor(
if (!valueAccessors) return null;

if (!Array.isArray(valueAccessors) && (typeof ngDevMode === 'undefined' || ngDevMode))
_throwError(dir, 'Value accessor was not provided as an array for form control with');
_throwError(
dir, 'Value accessor was not provided as an array for form control with',
'Please make sure that the `NG_VALUE_ACCESSOR` token is configured as a multi provider (with the `multi: true` property).');

let defaultAccessor: ControlValueAccessor|undefined = undefined;
let builtinAccessor: ControlValueAccessor|undefined = undefined;
Expand Down
3 changes: 2 additions & 1 deletion packages/forms/test/directives_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {fakeAsync, flushMicrotasks, tick} from '@angular/core/testing';
import {AbstractControl, CheckboxControlValueAccessor, ControlValueAccessor, DefaultValueAccessor, FormArray, FormArrayName, FormControl, FormControlDirective, FormControlName, FormGroup, FormGroupDirective, FormGroupName, NgControl, NgForm, NgModel, NgModelGroup, SelectControlValueAccessor, SelectMultipleControlValueAccessor, ValidationErrors, Validator, Validators} from '@angular/forms';
import {selectValueAccessor} from '@angular/forms/src/directives/shared';
import {composeValidators} from '@angular/forms/src/validators';

import {asyncValidator} from './util';

class DummyControlValueAccessor implements ControlValueAccessor {
Expand Down Expand Up @@ -53,7 +54,7 @@ class CustomValidatorDirective implements Validator {
it('should throw when accessor is not provided as array', () => {
expect(() => selectValueAccessor(dir, {} as any[]))
.toThrowError(
`Value accessor was not provided as an array for form control with unspecified name attribute`);
'Value accessor was not provided as an array for form control with unspecified name attribute.\nPlease make sure that the `NG_VALUE_ACCESSOR` token is configured as a multi provider (with the `multi: true` property).');
});

it('should return the default value accessor when no other provided', () => {
Expand Down

0 comments on commit 7e15ca1

Please sign in to comment.