Ability to set a custom message while working with `Validators`
See original GitHub issueWhich @angular/* package(s) are relevant/related to the feature request?
forms
Description
It is really intimating and obvious that in most cases we need to show custom messages to the user but IDK why we cannot specify the error message in the component’s class and we have to deal with it in a painful way in templates. Another thing is that this stackoverflow Q&A shows is that I am not alone 😄 .
Proposed solution
IMO it would be more readily to specify error message in the component’s class and then use a common component to show error messages as it is described here
So in login.component.ts
we have:
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
})
export class AComponent {
public loginForm: FormGroup;
public passwordSpecialChar = '!@#$&*';
public passwordShouldContainsSpecialChar = /(?=.*[!@#$&*])/;
public passwordShouldContainsOneLowercaseLetter = /(?=.*[a-z])/;
public passwordShouldContainsOneCapitalLetter = /(?=.*[A-Z])/;
public passwordShouldContainsOneDigit = /(?=.*[0-9])/;
constructor(private formBuilder: FormBuilder) {}
ngOnInit(): void {
this.loginForm = this.formBuilder.group({
username: [
'',
Validators.compose([
Validators.required({ customeMessage: 'Please enter username' }),
Validators.minLength(6, { customeMessage: 'Username should be at least 6 character' }),
Validators.maxLength(320, { customeMessage: 'Username cannot be more that 320 character' }),
Validators.pattern(/[\w_-\d]/, { customeMessage: 'Username can only contains alphanumeric, hyphens, and dashes' }),
]),
],
password: [
'',
Validators.compose([
Validators.minLength(8, { customeMessage: 'c message 1' }),
Validators.required({ customeMessage: 'c message 2' }),
Validators.pattern(this.passwordShouldContainsSpecialChar, { customeMessage: 'c message 3' }),
Validators.pattern(
this.passwordShouldContainsOneLowercaseLetter,
{ customeMessage: 'c message 4' }
),
Validators.pattern(
this.passwordShouldContainsOneCapitalLetter,
{ customeMessage: 'c message 5' }
),
Validators.pattern(this.passwordShouldContainsOneDigit, { customeMessage: 'c message 6' }),
]),
],
});
}
}
and in the login.component.html
we have:
<div>
<form [formGroup]="loginForm" (ngSubmit)="login(loginForm.value)">
<div>
<div>
<label for="username">username</label>
<span
class="text-danger"
*ngIf="loginForm.get('username').hasError('required')"
>
*
</span>
</div>
<div>
<!-- formControlName Syncs FormControl in an existing FormGroup instance to a form control element by name. -->
<input
placeholder="Enter your username"
type="text"
name="username"
id="username"
formControlName="username"
/>
</div>
<div
*ngIf="
loginForm.get('username').invalid &&
loginForm.get('username').errors &&
(loginForm.get('username').dirty ||
loginForm.get('username').touched)
"
>
<app-validation-errors
[errors]="loginForm.get('username').errors"
></app-validation-errors>
</div>
</div>
<div>
<div>
<label for="password">password</label>
<span
class="text-danger"
*ngIf="loginForm.get('password').hasError('required')"
>
*
</span>
</div>
<div>
<input
placeholder="Enter your Password"
type="password"
formControlName="password"
name="password"
id="password"
/>
</div>
<div
*ngIf="
loginForm.get('password').invalid &&
(loginForm.get('password').touched ||
loginForm.get('password').dirty)
"
>
<app-validation-errors
[errors]="loginForm.get('password').errors"
></app-validation-errors>
</div>
</div>
<div>
<div>
<button
[dissabled]="!loginForm.valid"
type="submit"
value="Login"
></button>
</div>
<div>Form Status: {{ loginForm.status }}</div>
</div>
</form>
</div>
and in the validation-errors.component.html
I could state error messages vividly
<ng-container
class="text-danger"
*ngIf="errors && errors['required']"
>
{{
errors['required'].customMessage ? errors['required'].customMessage : 'This field is required'
}}
</ng-container>
<!-- The same thing for the rest of it -->
Why am I motivated and think this is a unquestionable need?
I used to be a backend developer and I really appreciate class-validator. Now I came to learn Angular but I really feel that this is a dire need that has been forgotten or maybe it does not felt at all. BTW this is just an opinion.
Alternatives considered
Or at least we should have the power to change the default error message.
In the login.component.ts
:
/* ... */
Validators.required({ message: 'Please enter username' }),
/* ... */
Issue Analytics
- State:
- Created a year ago
- Reactions:7
- Comments:9 (5 by maintainers)
Top GitHub Comments
There are libraries doing somewhat what you want (like one I wrote: https://ngx-valdemort.ninja-squad.com/#/, even if custom messages are still specified in the template).
But even what you want can be done quite easily: you simply need to wrap the standard validators into your owns, and store the custom message in the error you return:
This issue has been automatically locked due to inactivity. Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.