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

Time:09-22

I have created a custom ValidationFn in angular. Somehow I allways 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!

CodePudding user response:

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

  • Related