Я был удивлен, когда узнал что в Angular нет кастомизации ошибок при валидации формы. То есть, встроенные билдеры форм есть, встроенные валидаторы есть, но вот встроенных текстов ошибок нет. Соответственно менять то нечего. Нужно создавать свои. А чтобы каждый раз не писать захардкоженый вывод ошибок, можно создать шаблон, в котором будет меняться только текст ошибок.
Создание формы
Создадим стандартную форму в Angular
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | Import { FormGroup, FormBuilder } from '@angular/forms'; export class MyFormPage { myForm: FormGroup; constructor(     private fb: FormBuilder,   ) {   } private createForm(): void {     this.myForm = this.fb.group({       name: ['', [Validators.required]],       email: ['', [Validators.required, Validators.email]],       phone: ['', Validators.minLength(7)],     });   } } | 
Что мы имеем?
3 поля с разными именами
3 разных валидатора- обязательное поле, емаил, валидация длины строки. Для каждого валидатора нужно понятное сообщение для показа пользователю.
Что предлагает Angular? Пример из официальной документации:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <div *ngIf="name.invalid && (name.dirty || name.touched)"     class="alert alert-danger">   <div *ngIf="name.errors.required">     Name is required.   </div>   <div *ngIf="name.errors.minlength">     Name must be at least 4 characters long.   </div>   <div *ngIf="name.errors.forbiddenName">     Name cannot be Bob.   </div> </div> | 
Расписывать каждый тип ошибки? На одно только поле их набралось три. А если это сложная форма регистрации с несколькими полями? Дублировать одно и то же. Ужас.
Другой путь
Напишем свое решение. Для начала нужно понять какое поле невалидное. Получить список полей не прошедших валидацию можно так:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | private getFormErrors(): Array<any> {     let result = [];     Object.keys(this.myForm.controls).forEach(key => {       const controlError: ValidationErrors = this.myForm.get(key).errors;       if (controlError) {         Object.keys(controlError).forEach(keyError => {           result.push({             'control': key,             'error': keyError,             'value': controlError[keyError],           });         });       }     });     return result;   } | 
После получения списка ошибок, нужно придумать для каждого текст. Воспользуемся наработками из Laravel and Yii2. Там для каждого поля в коде можно прописать свой текст.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 |  errorMessages = {     "required": "Введите {label}",     "email": "Email должен быть в формате myMail@almat.su",     "minlength": "Текущая длина {actualLength}. Минимальная длина должна быть {requiredLength} и более"   };   formLabels = {     "name": "Имя",     "email": "Емаил",     "phone": "Телефон",   }; | 
errorMessages — состоит из тип_ошибки: текст_ошибки
formLabels — чисто опционально, чтобы вместо сухого «Обязательное поле», «Введите значение в поле», было «Введите Имя» или «Введите Телефон»
Делаем подстановку сообщении:
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | private getFormErrors(): Array<Object> {     let result = [];  .....................         Object.keys(controlError).forEach(errorType => {           let message = this.formatMessage(fieldName, errorType, controlError);           result.push({ .......................             'value': controlError[errorType],             'message': message           });         });       }     });     return result;   }   formatMessage(fieldName: string, errorType: string, controlError: ValidationErrors): string {     let message: string;     if (errorType == "minlength") {       message = this.errorMessages[errorType]         .replace(/{actualLength}/, controlError[errorType].actualLength)         .replace(/{requiredLength}/, controlError[errorType].requiredLength);       console.log(message);     } else {       message = this.errorMessages[errorType].replace(/{label}/, this.formLabels[fieldName])     }     return message;   } | 
Обработчик при отправке формы:
| 1 2 3 4 5 6 7 8 9 10 11 12 |   myAwesomeSubmitHanlder(): void {     if (!this.myForm.valid) {       let errors = this.getFormErrors();       let toast = this.toastCtl.create({         message: errors[0].message,       });       toast.present();     }   } | 
Получился вот такой вывод:

 
			
			