angular: Unclear error message for badly configured custom form controls
Which @angular/* package(s) are relevant/releated to the feature request?
forms
Description
I was hitting the following error when implementing a custom form control:
ERROR Error: Value accessor was not provided as an array for form control with unspecified name attribute
at _throwError (forms.mjs:1752)
at selectValueAccessor (forms.mjs:1782)
at new FormControlName (forms.mjs:5743)
at NodeInjectorFactory.FormControlName_Factory [as factory] (forms.mjs:5827)
at getNodeInjectable (core.mjs:3556)
at searchTokensOnInjector (core.mjs:3493)
at getOrCreateInjectable (core.mjs:3437)
at ɵɵdirectiveInject (core.mjs:14720)
at ɵɵinject (core.mjs:4778)
at NodeInjectorFactory.factory (core.mjs:11563)
It was very unclear to me what this error message meant or how to fix it. My form controls all had names and formControlNames.
Only by uncommenting parts of my form could I even find the offending form control, since the error doesn’t specify what it was trying to do when the error occured.
Googling the error only brought up the source code for the test regarding this error, but there’s no explanation why an error is thrown there, either.
The actual error was that my form control was badly configured, i.e. it provided the NG_VALUE_ACCESSOR like this:
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: MyControl},
]
instead of this
providers: [
{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => MyControl), multi: true },
]
Maybe related? Maybe related: https://github.com/angular/angular/issues/3011
Here’s a reproduction: https://stackblitz.com/edit/angular-ivy-e2wj4z?file=src/app/app.component.ts
Proposed solution
Since I still don’t know the actual cause of the error, I can’t propose a solution to a clearer error message. It would be nice to know the class or form control something was trying to process when the error happens.
Andrew Kushnir proposed a solution:
I think we can improve the error message by including a note like this:
Value accessor was not provided as an array for form control with unspecified name attribute. Please make sure that the `NG_VALUE_ACCESSOR` token is configured as a multi provider (with the `multi: true` property).
I think there might also be an opportunity to improve the logic around getting the attribute name (so that there is a real name vs “unspecified attribute”).
Alternatives considered
—
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 15 (11 by maintainers)
@ameryousuf thanks for the comment. You are right, the inputs wouldn’t be available until the first
ngOnChanges
call. I think it might be a bit too risky to move thevalueAccessor
calculation to thengOnChanges
hook as there might be some code that would rely on it being available sooner than that… I think we should put this change on hold for now and we can come back to that once we do bigger refactoring in the future.@ameryousuf sure, please let me know if you have any questions. Thank you.
Hi @mwaibel-go, the mentioned error was caused by the missing
multi: true
in your code:which makes it a regular provider (vs a multi provider that the code expects). Here is the code location:
https://github.com/angular/angular/blob/8ebc946c0e7bf80d26ec8268acb4ff0af9e5c34a/packages/forms/src/directives/shared.ts#L317-L318
I think we can improve the error message by including a note like this:
I think there might also be an opportunity to improve the logic around getting the attribute name (so that there is a real name vs “unspecified attribute”). Could you please create a simple example of your structure using Stackblitz, so that we can look at the logic that calculates the name and see if there is a way to improve it?