[SOLVED] Angular: Cannot read properties of null (reading 'cannotContainSpace')

Issue

I have created a custom ValidationFn in Angular. Somehow I always get the following error message:

ERROR TypeError: Cannot read properties of null (reading
‘cannotContainSpace’)
at TutorRegistrationComponent_Template (template.html:31)
at executeTemplate (core.js:9545)
at refreshView (core.js:9414)
at refreshComponent (core.js:10580)
at refreshChildComponents (core.js:9211)
at refreshView (core.js:9464)
at renderComponentOrTemplate (core.js:9528)
at tickRootContext (core.js:10754)
at detectChangesInRootView (core.js:10779)
at RootViewRef.detectChanges (core.js:22792)

This is how I made the Validator:

export class UsernameValidators {

  static cannotContainSpace(control: AbstractControl): ValidationErrors | null {
    if ((control.value as string).indexOf(' ') >= 0) {
      console.log('username in validator (cannotContainSpace)', control.value);
      const valError: ValidationErrors = { cannotContainSpace: true };
      return { cannotContainSpace: true };
    }
    return null;
  }
}

This is how I used the Validator in my Page:

ngOnInit() {
  this.registrationForm = new FormGroup({
    username: new FormControl(
      '',
      [Validators.required, UsernameValidators.cannotContainSpace],
      UsernameValidators.shouldBeUnique
    ),
    password: new FormControl(''),


  });
}

and in my view:

<ion-item lines="full">
   <ion-label position="floating">Username</ion-label>
   <ion-input type="text" formControlName="username"></ion-input>
   <div
     *ngIf="username.errors.cannotContainSpace && username.touched"
     class="alert alert-danger"
   >
     Username cannot contain space.
   </div>
   <div
     *ngIf="username.errors.required && username.touched"
     class="alert alert-danger"
   >
     Username is required.
   </div>
   <div
     *ngIf="username.errors.shouldBeUnique && username.touched"
     class="alert alert-danger"
   >
     Username is already taken.
   </div>
   <div *ngIf="username.pending">Verfügbarkeit wird überprüft...</div>
</ion-item>

What am I doing wrong? Thank you a lot!

Solution

AbstractControl.errors possibly returns null. Hence you need to use Optional chaining (?.) for username.errors to prevent accessing chaining properties when it is null or undefined.

The ?. operator is like the . chaining operator, except that instead
of causing an error if a reference is nullish (null or undefined), the
expression short-circuits with a return value of undefined. When used
with function calls, it returns undefined if the given function does
not exist.

<div
  *ngIf="username.errors?.cannotContainSpace && username.touched"
  class="alert alert-danger"
>
  Username cannot contain space.
</div>
<div
  *ngIf="username.errors?.required && username.touched"
  class="alert alert-danger"
>
  Username is required.
</div>
<div
  *ngIf="username.errors?.shouldBeUnique && username.touched"
  class="alert alert-danger"
>
  Username is already taken.
</div>

Sample Solution on StackBlitz

Answered By – Yong Shun

Answer Checked By – Marie Seifert (BugsFixing Admin)

Leave a Reply

Your email address will not be published. Required fields are marked *