angular: TypeError: this._validator is not a function

๐Ÿž bug report

Affected Package

The issue is caused by package @angular/forms in combination with AOT compilation

Is this a regression?

Yes, the previous version in which this bug was not present was: Angular 8 without AOT.

Description

When binding dynamic validator values to an input via [maxlength]="maxLength" if AOT compilation is enabled the validation is attempted before the validator is created. An error is logged to the console: ERROR TypeError: this._validator is not a function.

๐Ÿ”ฌ Minimal Reproduction

https://github.com/nathanrobinson/angular_ivy_aot_validation_error

๐Ÿ”ฅ Exception or Error


ERROR TypeError: this._validator is not a function
    at MinLengthValidator.validate (VM1588 vendor.js:67057)
    at VM1588 vendor.js:60658
    at VM1588 vendor.js:60606
    at Array.map (<anonymous>)
    at _executeValidators (VM1588 vendor.js:60602)
    at VM1588 vendor.js:60547
    at VM1588 vendor.js:60606
    at Array.map (<anonymous>)
    at _executeValidators (VM1588 vendor.js:60602)
    at FormControl.validator (VM1588 vendor.js:60547)

๐ŸŒ Your Environment

Angular Version:


Angular CLI: 8.0.0                                             
Node: 10.14.2                                                  
OS: win32 x64                                                  
Angular: 8.0.0                                                 
... animations, cdk, cli, common, compiler, compiler-cli, core 
... forms, language-service, material, platform-browser        
... platform-browser-dynamic, router                           
                                                               
Package                           Version                      
-----------------------------------------------------------    
@angular-devkit/architect         0.800.0                      
@angular-devkit/build-angular     0.800.0                      
@angular-devkit/build-optimizer   0.800.0                      
@angular-devkit/build-webpack     0.800.0                      
@angular-devkit/core              8.0.0                        
@angular-devkit/schematics        8.0.0                        
@ngtools/webpack                  8.0.0                        
@schematics/angular               8.0.0                        
@schematics/update                0.800.0                      
rxjs                              6.4.0                        
typescript                        3.5.1                        
webpack                           4.30.0                       

Anything else relevant? The OnChange loop seems to call validate before setting the attributes, and then call it again after setting the attributes. There are three instances in https://github.com/angular/angular/blob/master/packages/forms/src/directives/validators.ts where this._validator is called without checking if it is null. This could be resolved for example by rewriting

validate(control: AbstractControl): ValidationErrors|null {
    return this.minlength == null ? null : this._validator(control);
  }

as

validate(control: AbstractControl): ValidationErrors|null {
    return this.minlength == null || !this._validator ? null : this._validator(control);
  }

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 19
  • Comments: 31 (6 by maintainers)

Commits related to this issue

Most upvoted comments

9.0.0-rc.1 still exist

I have same error, angular 9.0.0-next.8

My workaround, to be executed before bootstrapping the app module:

// https://github.com/angular/angular/issues/30784
function fixValidator(validator: any) {
	validator.prototype.validate = (function(original: any) {
		return function(this: PatternValidator) {
			if (!this['_validator'])
				return null

			return original.apply(this, arguments)
		}
	})(validator.prototype.validate)
}

fixValidator(MaxLengthValidator)
fixValidator(MinLengthValidator)
fixValidator(PatternValidator)

It wonโ€™t fix the other error though which is only raised in dev mode:

ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: โ€˜undefinedโ€™. Current value: โ€˜โ€™.

I have this bug as well.

I am using 9.0.0-next.5.

this.formBuilder.group({
     ...,
    displayName: new FormControl(model.displayName),
     ...
});
<mat-form-field>
     <input matInput maxlength="255" placeholder="displayName" type="text" class="form-control"  formControlName="displayName">
</mat-form-field>

core.js:5760 ERROR TypeError: this._validator is not a function at MaxLengthValidator.validate (forms.js:9048) at forms.js:1544 at forms.js:1492 at Array.map (<anonymous>) at _executeValidators (forms.js:1488) at forms.js:1430 at forms.js:1492 at Array.map (<anonymous>) at _executeValidators (forms.js:1488) at FormControl.validator (forms.js:1430)

~Still exists with 9.0.0-rc.4. Was hoping https://github.com/angular/angular/pull/33403 would be merged if it is indeed the fix~

I take it back, @anton-white is correct. It is fixed. Seems https://github.com/angular/angular/pull/33403 is not required.

This issue has been around for months and is now keeping us from switching to Ivy. Could someone take a look at the PR please? ๐Ÿ˜ƒ

Requirement: No validation necessary, just disallow user from entering any more characters

Angular version: 9 with Ivy and ReactiveFormsModule (FormsModule is also imported because I needed ngModel elsewhere) Using

<input matInput formControlName="someInput" maxlength="50" />

Is not working. I was expecting it to use the native browser behaviour, and it used to work in Angular 8, but it seems that now angular resolves the โ€˜maxlengthโ€™ attribute to an instance of MaxLengthValidator.

So, Instead of using maxlength, I used maxLength in the html instead, and it worked. This is either because

  • Angular decided to ignore it as maxLength is unrecognised, and then the browser corrected the โ€˜typoโ€™ or;
  • The html->maxlength attribute is angular->maxLength property

Can someone please clear my doubts on this, and explain why this is working like this?

RC.4 - no more error for PatternValidator!

Same here on RC.3 with Ivy. PatternValidator

Angular CLI: 9.0.0-rc.3
Node: 12.13.1
OS: linux x64
Angular: 9.0.0-rc.3
... animations, cli, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.14
@angular-devkit/build-angular     0.900.0-rc.3
@angular-devkit/build-optimizer   0.900.0-rc.3
@angular-devkit/build-webpack     0.900.0-rc.3
@angular-devkit/core              9.0.0-rc.3
@angular-devkit/schematics        8.3.14
@angular/cdk                      8.2.3
@angular/localize                 9.0.0-rc.0
@angular/material                 8.2.3
@ngtools/webpack                  9.0.0-rc.3
@schematics/angular               8.3.14
@schematics/update                0.900.0-rc.3
rxjs                              6.5.3
typescript                        3.6.4
webpack                           4.41.2