input-mask icon indicating copy to clipboard operation
input-mask copied to clipboard

Validators fails in a specific case

Open ssougnez opened this issue 3 years ago • 5 comments

I'm submitting a...

[ ] Regression (a behavior that used to work and stopped working in a new release)
[x] Bug report  
[ ] Performance issue
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request
[ ] Other... Please describe:

Current behavior

First of all, sorry for the elusive title but I couldn't come up with a meaningful one that does not take 3 lines of text :-)

Second, I could explain the issue but I think a StackBlitz will be clearer: https://stackblitz.com/edit/angular-uysvv8

Start by entering a number that satisfies the input in the textbox, hit "Switch" and re-enter a number. As you will see, when you enter the number the first time, the validator of input-mask works as expected. However, when you enter the number a second time, the validator says that the value is not correct while it is;

image

The code might seem weird but I'm using a similar one in the form I'm creating. Basically, the form contains two parts but only one of them is visible depending on the value of a radio button. However, these two parts ask to the user to enter the same field which an input mask is applied to, so in the case the user enters the value and changes the value of the radio button, the other part appears but then the input mask validation fails.

Expected behavior

The validator of the input mask should validate the value correctly.

Minimal reproduction of the problem with instructions

https://stackblitz.com/edit/angular-uysvv8

Environment

Angular CLI: 13.0.2
Node: 14.16.1
Package Manager: yarn 1.22.4
OS: win32 x64

Angular: 13.0.1
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1300.2
@angular-devkit/build-angular   13.0.2
@angular-devkit/core            13.0.2
@angular-devkit/schematics      13.0.2
@angular/cli                    13.0.2
@schematics/angular             13.0.2
rxjs                            7.4.0
typescript                      4.4.4

Browser:
- [x] Edge version 95
 
For Tooling issues:
- Node version: 14.16
- Platform:  Windows 

ssougnez avatar Nov 15 '21 14:11 ssougnez

After some investigations, it turns out this is because validators get stacked up each time the input get init. The solution would be to store the validator (it's raw but it's to expose the idea):

private _validator = this.validate.bind(this);

Use it when adding the validator:

const validators = this._ngControl.control.validator ? [this._ngControl.control.validator, this._validator] : [this._validator];

Then removing it in the OnDestroy

this._ngControl.control.removeValidators(this._validator)

Note that removeValidators has been introduced in Angular 12. Note also that I tried to use hasValidator instead of adding/removing it but it does not work as this is not the same => function reference not the same either.

ssougnez avatar Nov 17 '21 09:11 ssougnez

If you know the fix, you are most welcome to generate a PR.

shhdharmen avatar Nov 17 '21 09:11 shhdharmen

Okay, will do this week. I guess I'll have to make this PR for the beta branch as this one targets ng13 ?

ssougnez avatar Nov 17 '21 09:11 ssougnez

Yeah, I would say wait until we close #42 .

shhdharmen avatar Nov 17 '21 10:11 shhdharmen

@ssougnez can you raise a PR now?

shhdharmen avatar Dec 14 '21 08:12 shhdharmen

@ssougnez You need to use correct versions, please use following:

Angular: 13.3.11 (latest in v13) @ngneat/input-mask: 5.2.0 (latest for Angular 13)

shhdharmen avatar Oct 23 '22 07:10 shhdharmen