0
\$\begingroup\$

I am using a template for a text inputs and feedback messages to simplify my html code. This passes in variable string called label and populates the placeholder value for this input, and also uses the same string for the invalid-feedback message, but for the latter I want the correct a or an depending on if the label starts with a vowel or not. I currently use the registerOnTouched() function in text-input-component.ts as this is being called when the inputs are clicked/typed into to correct the feedback messages but I feel like there is a better solution/place to do this check.

Maybe something like a ternary operator or a pipe in the template?

And theoretically I could omit all the vowels except E from my check but that isn't future proof.

Form:

<app-text-input [formControl]="$any(loginForm.controls['email'])" [label]="'Email'" [type]="'email'"></app-text-input>
<app-text-input [formControl]="$any(loginForm.controls['password'])" [label]="'Password'" [type]="'password'"></app-text-input>

Text-Input Template CSS:

<div class="form-group">
  <input
    [class.is-invalid]="control.touched && control.invalid"
    type={{type}}
    class="form-control"
    [formControl]="control"
    placeholder={{label}}
  >
  <div *ngIf="control.errors?.['required']" class="invalid-feedback">Please enter a{{labelAfterVowelCheck}}</div>
</div>

Text-Input Template TypeScript:

import { Component, Input, Self } from '@angular/core';
import { ControlValueAccessor, FormControl, NgControl, PatternValidator } from '@angular/forms';

@Component({
  selector: 'app-text-input',
  templateUrl: './text-input.component.html',
  styleUrls: ['./text-input.component.css']
})
export class TextInputComponent implements ControlValueAccessor {
  @Input() label?: string;
  labelAfterVowelCheck = '';
  @Input() type: string = 'text';

  constructor(@Self() public ngControl: NgControl) {
    this.ngControl.valueAccessor = this; }
  writeValue(obj: any): void {
  }
  registerOnChange(fn: any): void {
  }
  registerOnTouched(fn: any): void {
    this.labelAfterVowelCheck = this.label!;
    if(["A","E","I","O","U","a","e","i","o","u"].some(vowel => this.label?.startsWith(vowel))){
      this.labelAfterVowelCheck = 'n ' + this.label;
    }
    else{
      this.labelAfterVowelCheck = ' ' + this.label;
    }
  }

  get control(): FormControl {
    return this.ngControl.control as FormControl;
  }
}
\$\endgroup\$
2
  • 2
    \$\begingroup\$ an honorable request, an hour, a used car, a one-armed bandit. The rule you are implementing is not correct. You need to consider the phonetics, not the spelling of the input. \$\endgroup\$
    – Flater
    Jan 10, 2023 at 22:48
  • \$\begingroup\$ @Flater oof, that didn't even occur to me, realistically because I am the only one providing the input text, I could just define some constants for the ones that require the n and just take the hit when I need another one \$\endgroup\$ Jan 11, 2023 at 9:29

1 Answer 1

2
\$\begingroup\$

Just a couple ideas:

  1. I might separate out the "validation" into its own function, isValid here, but you can create a better name. ie.
  registerOnTouched(fn: any): void {
    this.labelAfterVowelCheck = this.label!;
    if(isValid(this.label)){
      this.labelAfterVowelCheck = 'n ' + this.label;
    }
    else{
      this.labelAfterVowelCheck = ' ' + this.label;
    }
  }

With this change, it's easier to see that you don't need the first assignment (as it will be redone in the line below below). And as you hint at, a ternary dries it up a little:

  registerOnTouched(fn: any): void {
    this.labelAfterVowelCheck = (isValid(this.label) ? 'n ' : ' ') + this.label;
  }
  1. The validation itself can be simplified with a regular expression (although I get the sense this code is temporary). ie. /^[aeiou]/i.exec(label)

Hope this helps!

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for the prompt reply. The first assignment was actually a remnant of some previous logic that I forgot was still there. I have gone for idea 1. Would you say it could be better to create my own pipe for this or is that getting to complex for what it is? \$\endgroup\$ Jan 10, 2023 at 9:20

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.