Angular 2 form validation, minLength validator is not working
Asked Answered
C

8

62

I have following Angular 2 form:

<register>
    <form [ngFormModel] = "registrationForm">
        <div class = "form-group">
            <label class = "control-label" for="email">Email</label>
            <input class = "form-control" type="email" id="email" ngControl="email" #email="ngForm">
        </div>
        <div *ngIf = "email.touched && email.errors">
            <div *ngIf = "!email.errors.required && email.errors.underscoreNotFound" class = "alert alert-danger">
                <span>Underscore is required</span> 
            </div>
            <div *ngIf = "email.errors.required" class = "alert alert-danger">
                <span>Email is required</span>
            </div>
        </div>
        <div class = "form-group">
            <label class = "control-label" for="password">Password</label>
            <input class = "form-control" type="password" id="password" ngControl="password" #password="ngForm">
        </div>
        <div *ngIf = "password.touched && password.errors">
            <div *ngIf = "password.errors.minLength && !password.errors.required" class = "alert alert-danger">
                <span>Password should contain 6 characters</span>
            </div>  
            <div *ngIf = "password.errors.required" class = "alert alert-danger">
                <span>Password is required</span>
            </div>          
        </div>
    </form>
</register>

This is my Component where I have implemented validators:

import {Component} from '@angular/core';
import {Control, ControlGroup, FormBuilder, Validators} from '@angular/common';
import {CustomValidator} from './CustomValidator';

@Component({
    selector: 'register',
    templateUrl: './app/authentication/register_validation/register.html',
})

export class RegisterComponent{
    registrationForm: ControlGroup;

    constructor(formBuilder:FormBuilder)
    {
        this.registrationForm = formBuilder.group({
            email: ['',Validators.compose([Validators.required, CustomValidator.underscore])], 
            password: ['',Validators.compose([Validators.required,Validators.minLength(6)])]
        });
    }

}

In this form, email field is working fine for both validators i.e. when I do not type anything , it gives "Email is required" message, when I start typing something, it gives "Underscore is required" message and when I type "_" all error messages disappears. However, when I try to apply such 2 validators on password field, it's not working. When I do not type password it gives message as "Password is required". But when I type something less than 6 characters, minLength message doesn't appear at all. What is wrong in this code?

Cervin answered 27/6, 2016 at 23:8 Comment(8)
Can you please create a plnkr.co with your codeBakke
Also you are using lower version then RC3. which is deprecated. Try new RC3 versionSteradian
might refer this answer https://mcmap.net/q/323306/-how-can-i-implement-my-custom-validator-on-angular-2Watchmaker
@Watchmaker Yes. I did workaround by adding custom class for minLength but I wanted to use original validator. Anyways thanks :)Cervin
Original validator means default angular 2 ????Watchmaker
@Mayur Yes, Validators.minLength. However, now I'm facing similar issue for Validators.pattern. In this, it is showing me correct message when password pattern is invalid, but this error message remains as it is until end even if I write correct password. How can I deal with this issue?Cervin
Might need more details check have you return null when the condition is true so error message not remains on screenWatchmaker
I am facing similar issue. Were you able to find any solution?Expressman
V
147

The error key is minlength and not minLength:

<div *ngIf = "password.hasError('minlength') && !password.hasError('required')" class = "alert alert-danger">
  <span>Password should contain 6 characters</span>
</div>  
Vortex answered 9/11, 2016 at 14:35 Comment(4)
Your link is dead, but the solution still works. When you're still learning you'd think that Validators.maxLength would be checked by the identical key, especially since angular isn't afraid of camel casing everywhere else. But I guess it's mean to match HTML5 validators? Either way, thanks.Arius
The real question is why? I'm trying to add dynamic validations, so now I must call toLowerCase to get from the function to the error key? I hope it's at least consistent.Jutland
Three years later, and this is still a common problem. Thanks for the help! Why would they use a lowercase L?Gingham
This is still the same in Angular 10. I'm ok with it being in lowercase but still would like to know the rationale. Looks like this is not going to be changed anytime soon: github.com/angular/angular/issues/7407Attain
S
40

This really caught me out as well as I matched the key in my markup to what I had in code which is incorrect.

Sample Code

password1: ['', [Validators.required, Validators.minLength(8)]],

Sample Markup

*ngIf="registrationRequest.get('password1').hasError('minlength')"

Note in the code it's minlength entirely in lower case.

Sarmentose answered 20/9, 2017 at 19:16 Comment(2)
I forgot to add Validators.required. You saved a lot of my time. Thank you :)Chaplain
this is rather frustrating. Thanks!Nuggar
P
15

I was facing the same issue but after so many research I got a solution with this:
Use minlength instead of minLength
Here is the example:

<div *ngIf = "password.errors.minlength && !password.errors.required" class = "alert alert-danger">
      <span>Password should contain 6 characters</span>
    </div> 

Instead of:

<div *ngIf = "password.errors.minLength && !password.errors.required" class = "alert alert-danger">
  <span>Password should contain 6 characters</span>
</div>
Parch answered 11/7, 2019 at 5:9 Comment(1)
Until you didn't point this explicitly I was looking for the solution for half an hour, this should be mentioned in the documentation of angular, I don't see the benefit of designing form validators like this.Longford
H
7

I had the same problem where I wanted to validate a number field that contained the year, so I used Validators.maxLength(4) to make sure someone does not accidently type 5 numbers for a year. Turns out when you set the input type to number:

<input type="number" formControlName='year'>

then maxLength does not "work" anymore. Which actually makes sense if you think about it for half a second.

So I changed my date input to:

year: [null, [Validators.required, Validators.min(1990), Validators.max(2050)]],

Which is the right approach when working with a number field.

Hauser answered 7/9, 2020 at 13:55 Comment(0)
E
3

This worked for me for password validation.

<input type="password" class="form-control" name="password" placeholder="Password" [(ngModel)]="register.password" #password="ngModel" minlength="6" required>
Extramarital answered 14/11, 2019 at 10:10 Comment(0)
B
2

This might not really be related to the question asked here. But in my case, it was happening due to the input type defined in the HTML.

Validator was initiated like this in my case:

    this.OTPForm = this.fb.group({
        otp: [null, [Validators.required, Validators.minLength(6), Validators.maxLength(6)]]
    })

Validators.minLength and Validators.maxLength won't work for below as the input type is number/non-string hence the length cannot be really checked here.

    <input type="number" nz-input formControlName="otp" placeholder="Enter OTP" /> 

While for below where the input type is stated as "text", the comparison can be done. And so the Validators.minLength and Validators.maxLength worked here.

    <input type="text" nz-input formControlName="otp" placeholder="Enter OTP" />
Beneficial answered 7/12, 2021 at 3:56 Comment(0)
K
1
field: ['', Validators.compose([Validators.required, Validators.minLength(8)])]

This only works with multiple validators.

Kenley answered 14/11, 2019 at 10:1 Comment(0)
T
1

<div *ngIf = "password.errors.minLength && !password.errors.required" class = "alert alert-danger">
<span>Password should contain 6 characters</span>
</div> 

minLength must be lowercase minlength

Tibbetts answered 19/1, 2021 at 12:44 Comment(1)
I had the same issue and I used this syntax from above and it worked. However, there is a new requirement from Angular as below: <div *ngIf = "password.errors?.['minlength'] && !password.errors?.['required']" class = "alert alert-danger"> <span>Password should contain 6 characters</span> </div> This means it is optional to check errors on init. Without ?, we will have this error : Object is possibly 'null' and without [''] we have this Property '' comes from an index signature, so it must be accessed with [''].Harleigh

© 2022 - 2024 — McMap. All rights reserved.