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
improve error message for invalid value accessors when accessor is not provided as array
  • Loading branch information
ameryousuf committed Feb 24, 2022
1 parent bad5096 commit c104e66
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 c104e66

Please sign in to comment.