lionel
lionel

Reputation: 170

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

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!

Upvotes: 0

Views: 28203

Answers (1)

Yong Shun
Yong Shun

Reputation: 51450

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

Upvotes: 2

Related Questions