1

My source code can be access by the following URL:

https://stackblitz.com/edit/angular-aidmpq?file=src%2Fapp%2Fapp.component.html

I want to ask the following coding:

<mat-error *ngIf="logRecipients.errors.required">
    Appreciation Log Recipients is <strong>required</strong>
  </mat-error>
  <mat-error *ngIf="logRecipients.errors.logRecipientValidator">
    Invalid email address
  </mat-error>

Why the "logRecipients.errors.required" report the following error?

Cannot read property 'required' of null

Why the "logRecipients.errors.logRecipientValidator" prompt the following error?

Cannot read property 'logRecipientValidator' of null

I want to get the built-in "required" validator result to decide whether the "Appreciation Log Recipients is required" message is shown.

I want to get my custom validator result to decide whether the "Invalid email address" message is shown. In case, the validation failed, my validator would return an object {email:true}, how can I read this attribute?

0

5 Answers 5

2

I want to get my custom validator result to decide whether the "Invalid email address" message is shown. In case, the validation failed, my validator would return an object {email:true}, how can I read this attribute?

I think you are way over complicating it. Remember what you set in typescript as the return type of the custom validation

{[key: string]: any}

This is javascript. You can attach anything as a key value pair and grab that value reference using a string for the key. You can change the logic of the validation to alter the message based on what you want or return something new entirely. Just make sure your template accounts for all the scenarios. Below is an example of returning a message from the validation function:

validate(control: AbstractControl): {[key: string]: any}|null {
if ((control.dirty) && (control.valid)) {
  const logRecipients = control.value.trim().split('\n');
  const tempBox = this.renderer2.createElement('input');
  let result = null;
  tempBox.type = 'text';

  for (const logRecipient of logRecipients) {
    tempBox.value = logRecipient;
    result = (Validators.email(tempBox));
    // console.log(logRecipient + ',' + result);
    if (result != null) {
      break;
    }
  }
  // console.log('Return :' + result);
  console.log(result);
  return {email: 'The email address is invalid. Custom Message'};
} else {
  // console.log('Return null');
  return null;
}

App.component.html

 <form #callTreeEditForm="ngForm" (ngSubmit)="onSubmit(callTreeEditForm)">
<mat-form-field style="width:250px">
  <mat-label>Appreciation Log Recipients</mat-label>
  <textarea matInput
            cdkTextareaAutosize
            #autosize="cdkTextareaAutosize"
            cdkAutosizeMinRows="1"
            cdkAutosizeMaxRows="5"
            required
            name="logRecipients"
            #logRecipients="ngModel"
            logRecipientValidator
            [(ngModel)]="this.callTree.logRecipients"></textarea>
  <mat-error *ngIf="logRecipients.hasError('required')">
    Appreciation Log Recipients is <strong>required</strong>
  </mat-error>
  <mat-error *ngIf="logRecipients.hasError('email')">
    {{logRecipients.errors['email']}}
  </mat-error>
</mat-form-field>

Sign up to request clarification or add additional context in comments.

Comments

1

You should first check whether logRecipients.errors is empty, null or undefined or not, then you check for the specific errors.

so change your code like below:

line 14 has 2 changes:

  1. required validation is inside the errors object so change <mat-error *ngIf="logRecipients.required">to <mat-error *ngIf="logRecipients.errors.required">.
  2. check for errors object itself, so change <mat-error *ngIf="logRecipients.errors.required"> to <mat-error *ngIf=" logRecipients.errors && logRecipients.errors.required">

line 17 has the same issue (check for the errors object itself), change *ngIf="logRecipients.errors.logRecipientValidator" to *ngIf="logRecipients.errors && logRecipients.errors.logRecipientValidator"

full working code:

  <form #callTreeEditForm="ngForm" (ngSubmit)="onSubmit(callTreeEditForm)">
    <mat-form-field style="width:250px">
      <mat-label>Appreciation Log Recipients</mat-label>
      <textarea matInput
                cdkTextareaAutosize
                #autosize="cdkTextareaAutosize"
                cdkAutosizeMinRows="1"
                cdkAutosizeMaxRows="5"
                required
                name="logRecipients"
                #logRecipients="ngModel"
                logRecipientValidator
                [(ngModel)]="this.callTree.logRecipients"></textarea>
      <mat-error *ngIf="logRecipients.errors &&logRecipients.errors.required">
        Appreciation Log Recipients is <strong>required</strong>
      </mat-error>
      <mat-error *ngIf="logRecipients.errors && logRecipients.errors.logRecipientValidator">
        Invalid email address
      </mat-error>
    </mat-form-field>

  </form> 

Hope this help. :)

3 Comments

The first problem is solved. However, the 2 nd problem does not. Anyway, thank you for your effort.
Could you please explain the second problem more.
I want to get my custom validator result to decide whether the "Invalid email address" message is shown. In case, the validation failed, my validator would return an object {email:true}, how can I read this attribute?
1

At some point logRecipients is undefined, to address that just check if that is present then go for subsequent property checks on that object.

  <mat-error *ngIf="logRecipients && logRecipients.required">
    Appreciation Log Recipients is <strong>required</strong>
  </mat-error>
  <mat-error *ngIf="logRecipients && logRecipients.errors && logRecipients.errors.logRecipientValidator">
    Invalid email address
  </mat-error>

1 Comment

use safe operator
1

just use angular already provide us... template expression operator ( ? ). So now, your checking if property is defined or not by making them optional.

<mat-error *ngIf="logRecipients?.errors?.logRecipientValidator">
    Invalid email address
</mat-error>

Comments

0

Sorry, I forgot to add the directive to the app.module.ts.

And I found the solution as below:

  <mat-error *ngIf="logRecipients.hasError('required')">
    Appreciation Log Recipients is <strong>required</strong>
  </mat-error>
  <mat-error *ngIf="logRecipients.hasError('email')">
    Invalid email address
  </mat-error>

The working code can be accessed by the following URL:

https://stackblitz.com/edit/angular-aidmpq?file=src%2Fapp%2Fapp.component.html

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.