0

This is in Angular, I want to use variable to change my conditional statement so I don't need to modify every variable and type again This is a code in input tag HTML .

import { FormBuilder, FormGroup, Validators } from '@angular/forms';

.

    public form: FormGroup;
    private formBuilder: FormBuilder

.

   get f() { return this.form.controls; }

.

   this.form = this.formBuilder.group({
      id: ['00000000-0000-0000-0000-000000000000'],
      name: ['', Validators.required],
      email: ['', [Validators.required, Validators.pattern("^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$")]],
      oraganize: ['', Validators.required],

    });

.

<input
    ...
    [ngClass]="{'is-invalid': f.name.invalid && (f.name.dirty || f.name.touched)}"
>

So my code will change every time when there is a new input such as name, email, oraganize, etc

I want to build a function that I can pass some string and make it super nice not to modify all the time with the long line. ex:

  public checkCondition(attribute: string): boolean{
    return (`this.f.${attribute}.invalid && (this.f.${attribute}.dirty || this.f.${attribute}.touched)`);
  }

so I can use as...

<input
    ...
    [ngClass]="{'is-invalid': checkCondition("name")}"
>

Please, So can I do it this way or not? or does it just works with only the string, not the condition?

Sirawit
  • 129
  • 1
  • 10
  • 1
    This should be possible, but it may be helpful to post more of your code (like what `this.f` is). With typescript you should have access to complex types, and each field likely has the same types. In your example name, email, address all should have the same type which has fields dirty, invalid. touched. Instead of passing the name to the function, just pass the object itself checkCondition(f.name). Then in your checkCondition function you can check thing.valid, thing.dirty etc etc... – Zen Oct 26 '21 at 19:33
  • Specifying what you are using is important to get the best answers for your question. I'm guessing that you may be using input fields or forms in some combination. If that is the case, I'm positive that there are questions and answers already on this site that address your concerns. Maybe this one? https://stackoverflow.com/questions/43553544/how-can-i-manually-set-an-angular-form-field-as-invalid – Zen Oct 26 '21 at 19:37
  • Oh, I forgot :P, I have added some more necessary code. check it out! – Sirawit Oct 26 '21 at 19:48
  • Nah, I don't get it that post (may be I'm to Newby @-@) but I think that is not what I mean to, But btw Thank you very much :) – Sirawit Oct 26 '21 at 19:53

1 Answers1

1

it looks like you where very close. this should work.

public checkCondition(key: string): boolean{
    return this.f[key].invalid && (this.f[key].dirty || this.f[key].touched);
  }

or you can further simplify it

public checkCondition(key: string): boolean{
    return {
      'is-invalid': this.f[key].invalid && (this.f[key].dirty || this.f[key].touched) 
    };
  }

and you html

<input [ngClass]="checkCondition('name')" />

Here is what it would look like all together

import { Component } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css'],
})
export class AppComponent {
  form = this.formBuilder.group({
    id: ['00000000-0000-0000-0000-000000000000'],
    name: ['', Validators.required],
    email: ['', [Validators.required, Validators.pattern("^[a-z0-9._%+-]+@[a-z0-9.-]+\\.[a-z]{2,4}$")]],
    oraganize: ['', Validators.required],
  });

  constructor(private formBuilder: FormBuilder) {}

  checkCondition(key: string) {
    const control = this.form.get(key);

    if (!control) {
      return;
    }

    return {
      'is-invalid': control.invalid && (control.dirty || control.touched) 
    };
  }

}
<form [formGroup]="form">
  <input formControlName="id" [ngClass]="checkCondition('id')" />
  <input formControlName="name" [ngClass]="checkCondition('name')" />
  <input formControlName="email" [ngClass]="checkCondition('email')" />
  <input formControlName="oraganize" [ngClass]="checkCondition('oraganize')" />
</form>

Here is a working stackBlitz

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

DrakeAnglin
  • 718
  • 1
  • 4
  • 12
  • interesting, let me try – Sirawit Oct 26 '21 at 19:54
  • the first one look very nice but the 2rd it's great but can't return with boolean because you have 'is-invalid' combination here -> i try to change from boolean to any – Sirawit Oct 26 '21 at 19:57
  • Wow, Amazing! Your code work great. But please edit from return "boolean" to "any" of your 2rd block code :) Thank you very much – Sirawit Oct 26 '21 at 20:01
  • more question Drake. What is mean this.f[key] btw. i wonder how that code work? – Sirawit Oct 26 '21 at 20:02
  • Um... I have an error now, Idk why? it said core.js:4080 ERROR TypeError: Cannot read properties of undefined (reading 'invalid') – Sirawit Oct 26 '21 at 20:36
  • 1
    this is referred to as bracket notation. You should only use this when trying to access a key in a object and the key is a variable. There is a good article here https://codeburst.io/javascript-quickie-dot-notation-vs-bracket-notation-333641c0f781 Please mark as the accepted answer if this worked for you. – DrakeAnglin Oct 26 '21 at 20:42
  • your error is due to the value `this.f` is undefined. Is `this.f` defined in your app? it may help if you added a stackblitz – DrakeAnglin Oct 26 '21 at 20:44
  • already sir, but more more worst is... when i use function, it will return true/false to all of those who use function with different parameter ... it is very weird situation for me (aka. i'm fucked up) – Sirawit Oct 26 '21 at 20:49
  • i have update the answer with a link to a working stackblitz – DrakeAnglin Oct 26 '21 at 21:08
  • thanks, update from me i try to check if it can read or not, the result is it can console log to see the value of invalid is true or false but it have error after that true/false is that i mention above – Sirawit Oct 26 '21 at 21:17
  • did you see my code? – Sirawit Oct 26 '21 at 21:21
  • i need to go to sleep, i put almost every thing in it (only researcher) – Sirawit Oct 26 '21 at 21:31
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/238576/discussion-between-sirawit-and-drakeanglin). – Sirawit Oct 26 '21 at 21:35