3

For example, the Angular documentation here uses the following directive for the forbiddenName validation:

@Directive({
  selector: '[appForbiddenName]',
  providers: [{provide: NG_VALIDATORS, useExisting: ForbiddenValidatorDirective, multi: true}]
})
export class ForbiddenValidatorDirective implements Validator {
  @Input('appForbiddenName') forbiddenName: string;

  validate(control: AbstractControl): {[key: string]: any} {
    return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName, 'i'))(control)
                              : null;
  }
}

Is it possible to use a @Input of say Object or string[] instead of only allowing strings? If not, how do you pass in multiple arguments?

The Angular docs uses it in the example as such:

<input id="name" name="name" class="form-control"
       required minlength="4" appForbiddenName="bob"
       [(ngModel)]="hero.name" #name="ngModel" >

1 Answer 1

4

Multiple strings with a separator

You can pass multiple strings with a separator.

For example, I defined a range validator as follows:

                    <input class="form-control" 
                            id="inputStarRating" 
                            type="text" 
                            placeholder="Rating"
                            mhRange="1,5"
                            [(ngModel)] = "movie.starRating"
                            name="starRating"
                            #starRatingVar = "ngModel" />

The directive then had code as follows:

  constructor(@Attribute('mhRange') range: string) {
    const arr = range.split(',');
    let min = 1;
    let max = 10;
    if (arr[0]) { min = parseInt(arr[0], 10); }
    if (arr[1]) { max = parseInt(arr[1], 10); }
    this.validator = NumberValidators.range(min, max);
  }

Notice that this uses a split to pull apart the two different values.

Arrays

You can also pass arrays like this:

  @Input('appForbiddenName') forbiddenName: string[];

  validate(control: AbstractControl): {[key: string]: any} {
    console.log(this.forbiddenName);
    return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName[0], 'i'))(control)
                              : null;
  }

NOTE: To minimize changes in the above code, I just checked the first element. But you could change it to loop through the array.

The HTML then looks like this:

    <input id="name" name="name" class="form-control"
           required minlength="4" [appForbiddenName]="powers"
           [(ngModel)]="hero.name" #name="ngModel" >

Notice how it uses binding to bind to the array of values.

Objects

You can define objects like this:

  @Input('appForbiddenName') forbiddenName: Hero;

  validate(control: AbstractControl): {[key: string]: any} {
    console.log(this.forbiddenName);
    return this.forbiddenName ? forbiddenNameValidator(new RegExp(this.forbiddenName.alterEgo, 'i'))(control)
                              : null;
  }

Assuming there is a type Hero defined. For the sample app from the documentation, I had to use any because no Hero type was defined.

The HTML then looks like this:

    <input id="name" name="name" class="form-control"
           required minlength="4" [appForbiddenName]="hero"
           [(ngModel)]="hero.name" #name="ngModel" >

Bottom line, you cannot pass anything but a string to the attribute, but that string can be a binding.

So doing something like this:

appForbiddenName='{"name":"Dr.", "alterEgo":"Dr. What", "power":"test"}'

Just provides it as a string. You'd have to write the code to parse it and turn it back into an object:

  @Input('appForbiddenName') forbiddenName: string;

  validate(control: AbstractControl): {[key: string]: any} {
    const hero: Hero = JSON.parse(this.forbiddenName);
    console.log(hero.alterEgo);
    return this.forbiddenName ? forbiddenNameValidator(new RegExp(hero.alterEgo, 'i'))(control)
                              : null;
  }
Sign up to request clarification or add additional context in comments.

1 Comment

DeborahK, I tried to pass in an Object to give my code more description. But I had a hard time escaping the characters in a regular Object. I'm guessing this with the separator and split is the best approach. Feels kinda bad. Do you know why only strings are accepted?

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.