0

I'm trying to make a required validation to my checkboxes.

My TS file :

public colors: Array<any> = [
     { description: 'White', value: 'White' },
     { description: 'Black', value: 'Black' },
     { description: 'Blue', value: 'Blue' },
     { description: 'Green', value: 'Green' },
     { description: 'Yellow', value: 'Yellow' },
     { description: 'Red', value: 'Red' },
];
    
constructor(
    private formBuilder: FormBuilder,
    private heroService: HeroService,
    private toastr: ToastrService
  ) {
  this.fromInit();
}

ngOnInit(): void {}

fromInit() {
  this.heroCreateForm = this.formBuilder.group({
    suitColors: new FormArray([], [Validators.required]),
  });
}

onCheckChange(event) {
  const formArray: FormArray = this.heroCreateForm.get(
    'suitColors'
  ) as FormArray;

  if (event.target.checked) {
    formArray.push(new FormControl(event.target.value));
  } else {
    let i: number = 0;

    formArray.controls.forEach((ctrl: FormControl) => {
      if (ctrl.value == event.target.value) {
        formArray.removeAt(i);
        return;
      }
      i++;
    });
  }
}


invalidSuitColorsMessage() {
   // this function doesn't work
   if (this.suitColors.errors?.required)
      return "You must choose the hero's suit colors";
}

My HTML file :

<div class="main-content">
  <form [formGroup]="heroCreateForm" (ngSubmit)="createHero()">
    <div class="container">

      <div class="input-container-suitColors-input">
        <label><b>Suit colors: </b></label>
        <ng-container *ngFor="let color of colors; let i=index">
          <div class="radio-contatiner">
            <input type="checkbox"
                   [value]="color.value"
                   (change)="onCheckChange($event)">
            {{color.description}}
          </div>
        </ng-container>
      </div>

      <div class="invalid-input-message"
           *ngIf="suitColors.touched && suitColors.invalid">{{invalidSuitColorsMessage()}}</div>

// here is the issue. I'm getting here an error

      <hr>

      <button type="submit"
              class="registerbtn"
              [disabled]="heroCreateForm.invalid">Register</button>
    </div>
  </form>
</div>

Error

Cannot read properties of undefined (reading 'touched')

I do understand why it does work. I search online and didn't find any solution to my issue.

I'm trying to show a message if the required error happens on those checkboxes

Does anyone can take a look and explain to me why does it happen and how should I fix it?

4
  • 1
    Does this answer your question? Detecting an undefined object property Commented Dec 5, 2021 at 20:37
  • The object suitColors is undefined, you should check at this. Lot of information about the undefined error are on multiple SO question like this one, or this Commented Dec 5, 2021 at 20:40
  • Hi i didn't really find any way to fix it from those articles How would you make the validation ? Commented Dec 5, 2021 at 20:45
  • Let me make an answer to explain how to fix it Commented Dec 5, 2021 at 20:46

1 Answer 1

0

The error said the variable touched can't be found because the object that should contains it is not defined. In other language it's also called as null. More explaination about undefined

In your case, suitColors is not defined. So there is multiple ways :

  1. You can define it. For example, in the constructor like that:
constructor(private formBuilder: FormBuilder, private heroService: HeroService,
   private toastr: ToastrService, public suitColors: MyObject) {
   this.fromInit();
}

Or as public variable like that :

public suitColors: MyObject;

constructor(private formBuilder: FormBuilder, private heroService: HeroService, private toastr: ToastrService) {
   this.suitColors = new MyObject();
   this.fromInit();
}
  1. Check in the *ngIf before use it. With this way, you should add a check for ALL object. Also, this will work everytime, even if you define object after ngInit.
<div class="invalid-input-message"
           *ngIf="suitColors != null && suitColors.touched && suitColors.invalid"> 
    {{invalidSuitColorsMessage()}}
</div>
Sign up to request clarification or add additional context in comments.

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.