1

My form is prefilled with user.email. I wish to only enable the edit button if the user fills the FormControl's field with a value other than the original user.email. Is it possible to do this with a custom Validator?

This is my validator:

import { FormControl } from  '@angular/forms';

export class ChangedValidator {
   static isValid(control: FormControl): any {
     let initialValue = (' ' + control.value).slice(1);

     if(initialValue === control.value){
            return {
                "changed": true
            };
        }
      return null;
   }
}

The intention was to clone the FormControl.value, but I realize that this class is instantiated every time a value is changed in the FormControl.

One very hacky approach, that writes unreusable code is to fetch user.email from the data provider that stores it, and use it to compare it with the FormControl.value. As you may guess, the validator will ONLY work for the User object's parameters, and nothing else.

I want to write a universal Validator that checks if the form's current value is different from the value that was initialized.

Edit:

This is a way to do it with pristine, but it's not perfect.

import { FormControl } from  '@angular/forms';

export class ChangedValidator { 
   static isValid(control: FormControl): any {

     if(control.pristine){
            return {
                "unchanged": true
            };
        }
      return null;
   }
}
Ka Mok
  • 1,937
  • 3
  • 22
  • 47
  • If `pristine` isn't good enough (checks if the value changed, not if it changed and reverted to original), then, yes, you could do a custom validator where you send in the initial value as a parameter. – silentsod Dec 14 '16 at 20:07
  • @silentsod `pristine` is probably "good enough", but if possible can you show me how to send it in? I looked at the other thread, but none of those solutions worked for me when I tried it. – Ka Mok Dec 14 '16 at 20:15

1 Answers1

3

If you need to check that things have changed from the initial value and not just that the control is no longer pristine; as in, it could return to its initial value and you don't want the error, then you can implement a validation function as follows:

static isValid = (initialValue: any): any => {
  return(control: FormControl) => {
   console.log(control.value);

     if(JSON.stringify(initialValue) !== JSON.stringify(control.value)) {
       return {
              "changed": true
          };
     }
    return null;
  }
}

Note that is a quick and dirty object check and that there was already an answer on custom validators with parameters and an explanation of the custom validation as a function factory but that's a little thin on details.

The forbiddenNamevalidator factory returns the configured validator function. That function takes an Angular control object and returns either null if the control value is valid or a validation error object. The validation error object typically has a property whose name is the validation key ('forbiddenName') and whose value is an arbitrary dictionary of values that we could insert into an error message ({name}).

Here's a playground

Community
  • 1
  • 1
silentsod
  • 8,165
  • 42
  • 40
  • The playground doesn't work anymore, the preview loads for life. I've tested the way you do, control.value and initialValue will have ever the same value. – crg May 24 '21 at 20:55