Ругается что объект возможно нулевой

Создаю форму в компоненте

export class LoginPageComponent implements OnInit {

  form!: FormGroup

  constructor() { }

  ngOnInit() {
    this.form = new FormGroup({
      email: new FormControl(null, [Validators.required, Validators.email]),
      password: new FormControl(null, [Validators.required, Validators.minLength(6)]),
    })
  }

}

В html выполняю проверки ввода значений

<div *ngIf="form.get('email').touched && form.get('email').invalid" class="validation">
  <small *ngIf="form.get('email').errors.required">Enter Email</small>
  <small *ngIf="form.get('email').errors.email">Enter valid Email</small>
</div>

На каждую строку, где встречается form IDEA ругается

error TS2531: Object is possibly 'null'

Я так понимаю, что это связано с тем что создание объекта происходит в ngOnInit. Проставил везде знак "?" и IDEA перестает ругаться:

<div *ngIf="form.get('email')?.touched && form.get('email')?.invalid" class="validation">
  <small *ngIf="form.get('email')?.errors.required">Enter Email</small>
  <small *ngIf="form.get('email')?.errors.email">Enter valid Email</small>
</div>

Но на сколько это правильно? Может есть более корректное решение этой проблемы? Может я не правильно создаю объект FormGroup?


Ответы (2 шт):

Автор решения: Sergey Glazirin

Компилятор ругается на метод form.get().

Согласно документации он возвращается или AbstractControl | null

Соответственно вы пытаетесь получить свойство touched следующим образом form.get('email').touched. Так как потенциально там может быть null, то свойство tuched получить невозможно.

Вариант с optionalChaining (знак вопроса после метода get), которым вы решили проблему - вполне нормальный способ.

И также можно вынести form.get('email') в геттер, как это сделано в документации

get emailControl() {
  return this.profileForm.get('email') as AbstractControl;
}

Тогда в шаблоне можно будет писать так

<div *ngIf="emailControl?.touched && emailControl?.invalid" class="validation">
  <small *ngIf="emailControl?.errors.required">Enter Email</small>
  <small *ngIf="emailControl?.errors.email">Enter valid Email</small>
</div>
→ Ссылка
Автор решения: Alexander Chernin

Можно сделать так:

<div *ngIf="email" class="validation">
  <ng-container *ngIf="email.errors">
    <small *ngIf="email.errors.required">Enter Email</small>
    <small *ngIf="email.errors.email">Enter valid Email</small>
  <ng-container
</div>

ts:

get email() {
    const em = this.form.get('email');
    return em && em.touched && em.invalid ? em: null;
}
→ Ссылка