question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

strictly-typed forms do not check CVAs or template bindings

See original GitHub issue

Which @angular/* package(s) are the source of the bug?

forms

Is this a regression?

No

Description

See the stackblitz below.

TL;DR even though we use a FormControl<number>, its value can be null, simply because the CVA of inputs of type number sets the value to null.

The strictly-typed forms are not very consistent, IMHO, regarding the type insurance they provide. For example:

  • they force us to have nullable values just in case one calls reset(), which unfortunately sets the value to null, unless we explicitly use the option initialValueIsDefault. Even though, in my experience, calling reset() is extremely rare.
  • they force us to have undefined-able values in form groups just in case one would disable a control, thus making its value absent of the form group’s value. Disabling fields is more common in my experience than calling reset(), but still quite rare.

But on the other hand:

  • they don’t care at all if the CVA used to set the control’s value sets it to null (like in the example in the stackblitz). Using number inputs, or select boxes with a default null option, for example, is extremely common in my experience. And in that case, the non-nullability of the FormControl is a lie.

I would expect more consistency:

  • either forms are paranoid, and don’t ever let the typing lie, but in that case, a form control initialized with the initialValueIsDefault option and a non null initial value should check that its value is never set to null and throw if it’s the case (like in the provided example)
  • or forms should give the control of the type to the developer: if they know that they never call reset(), and that they never disable a control, and that the CVA never sets the value to null, then let them choose the type they want, and too bad for them if they screwed up (i.e. basically what happens every type you do http.get<Something>())

Please provide a link to a minimal reproduction of the bug

https://stackblitz.com/edit/angular-tjtyng-kz6zuz?file=src%2Fapp%2Fapp.module.ts,src%2Fapp%2Fapp.component.html,src%2Fapp%2Fapp.component.ts,package.json,src%2Fstyles.scss,angular.json,src%2Findex.html

Please provide the exception or error you saw

NA

Please provide the environment you discovered this bug in (run ng version)

Angular 14.0.0-rc.0

Anything else?

No response

Issue Analytics

  • State:open
  • Created a year ago
  • Reactions:10
  • Comments:6 (6 by maintainers)

github_iconTop GitHub Comments

7reactions
dylhunncommented, May 12, 2022

Hello, thanks for this feedback.

Our general intention with Forms types is to be as strict as possible (or “paranoid,” you might say). Currently, the types account for all the null and undefined possibilities coming from the TypeScript side.

However, there is currently no integration with ControlValueAccessor whatsoever. This means the issue is actually much larger than a CVA setting the control to null – the CVA could set the control to a value of a completely unrelated type! i.e., you can bind a FormControl<string> to an input type="number", and there will be no type error.

This is something we intend to fix down the road – we discussed in the RFC whether to delay this feature until CVA and template type checking integrations are ready, but we decided not to. In particular, although the template types are not as rich as TypeScript, we should be able to produce some warnings in the future about type misalignments.

P.S. Regarding your comment about the undefined disabled controls – if you’re not sensitive to the disabled state of controls, I strongly suggest moving to .getRawValue() instead of .value!

P.P.S. If you don’t set initialValueIsDefault, then null will remain in your type, which is indeed a bit safer if the CVA is frequently setting the control to null.

0reactions
angular-robot[bot]commented, Jul 15, 2022

Thank you for submitting your feature request! Looks like during the polling process it didn’t collect a sufficient number of votes to move to the next stage.

We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular’s scope, we’d encourage you to collaborate with the community on publishing it as an open source package.

You can find more details about the feature request process in our documentation.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Typed Forms - Angular
As of Angular 14, reactive forms are strictly typed by default. ... With strictly typed reactive forms, the above code does not compile,...
Read more >
Angular Strictly Typed Forms (Complete Guide)
Learn the best way to leverage Angular Typed Forms in your projects. Add type safety to your form code by relying mostly on...
Read more >
How to use ControlValueAccessor to enhance date input with ...
I want my custom CVA component to be marked red also when an external validator is invalid (i.e. Validators.required set on the FormControl...
Read more >
RFC: Strictly Typed Reactive Forms Gotchas Every Angular ...
Template -driven Forms and Control Bindings. Angular's template type checking engine will not be able to assert that the value produced by the ......
Read more >
Investigating the Angular typed form RFC prototype
“We will not block this feature on template type checking improvements, validators, or CVAs. We may land improvements in these areas, possibly ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found