0

I have implemented a generic custom validator as a function looking like this:

export function validate(control: AbstractControl, validation: boolean,
                         errObj: { [key: string]: boolean }): null | { [key: string]: boolean } {
    const toCheck: string = control.value;
    if (!toCheck || validation) {
        return null;
    } else {
        return errObj;
    }
}

pretty easy and straight forward: It gets the value from the form control and if the value is defined or it passes the condition given on a parameter it returns null, else an errorobj.


Now i want to assign this custom validator on a control, but I dont know how to pass the current Abstractcontrol. I've tried something like this:

private formBuilder: FormBuilder = new FormBuilder();

public setForm(form: SomeType): FormGroup {
    return this.formBuilder.group({
        days: [form.days],
        ...
        useDefaultRule: [form.useDefaultRule],
        urls: this.formBuilder.group({
            webUrl: [form.urls.webUrl, [validate(new FormControl(),
                hasWebURLPattern(new FormControl().value),
                {webUrl: true})]]
        })
    });
}

But this does not work. How do I pass the current formcontrol as a parameter?

1 Answer 1

2

I think that you didn't write you validator in the right way.

Try this instead.

export function validate(callback: Function, error: string): ValidatorFn {
  return (control: FormControl) => {
    return control.value && callback(control.value) ? { [error]: true } : null;
  };
}

You can call it with

webUrl: ['', [validate(hasWebURLPattern, 'webUrl')]]

It works by giving in a function, that will be called with the value of the form control directly into the validator. You also provide directly an error string, reducing effectively the code complexity.

Also, don't forget that you will lose your this context : if your callback has this references in it, add this to your call :

webUrl: ['', [validate(hasWebURLPattern.bind(this), 'webUrl')]]
Sign up to request clarification or add additional context in comments.

4 Comments

U re a beast, thanks!^^ But you should modify your solution to this: export function validate(condition: boolean, error: string): ValidatorFn { return (control: FormControl) => { return control.value && condition ? {[error]: true} : null; }; }
@Fantasia well that was my first code piece, but you were using a function that takes in the control value. If you use a boolean as a parameter, you won't be able to check the control value ...
hmm yeah.. you´are right it has to be a function. My working solution is this: export function validate(callback: Function, error: string): ValidatorFn { return (control: FormControl) => { return (!control.value || callback(control.value)) ? null : { [error]: true }; }; }
@Fantasia yeah you DeMorganed it, I have edited my answer to shorten it wth control.value && callback(control.value) ?

Your Answer

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