Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic validation error messages #473

Open
fracz opened this issue Jan 4, 2018 · 6 comments
Open

Dynamic validation error messages #473

fracz opened this issue Jan 4, 2018 · 6 comments
Labels

Comments

@fracz
Copy link

fracz commented Jan 4, 2018

I'm submitting a feature request

Currently, it is impossible to create a dynamic validation error message. For example, I want to validate IBAN account number. I configure the rule as follows:

ValidationRules
    .ensure('account').displayName("Account number")
    .satisfies(account => getActualChecksum(account) == calculateChecksum(account))
    .withMessage("Given IBAN number is invalid");

The validation message could be much more informative, for example Given IBAN number has cheksum 34 but it should be 56.

What about allowing to pass a callback that will generate a validation message based on given value? This should solve all of the cases where the validation message should be built based on the given value or something else dynamic.

ValidationRules
    .ensure('account').displayName("Account number")
    .satisfies(account => getActualChecksum(account) == calculateChecksum(account))
    .withMessage(account => "Given IBAN has checksum " + getActualChecksum(account) + " but it should be " +calculateChecksum(account));

OR it should be possible to define special parameters for message in addition to existing $displayName and $value, e.g.

ValidationRules
    .ensure('account').displayName("Account number")
    .satisfies(account => getActualChecksum(account) == calculateChecksum(account))
    .withMessage("Given IBAN has checksum ${actualChecksum} but it should be ${correctChecksum}")
    .withMessageParamsBuilder(account => {actualChecksum: getActualChecksum(account), correctChecksum: calculateChecksum(account)});

What do you think?

@jdanyow
Copy link
Contributor

jdanyow commented Jan 5, 2018

you could do this:

.withMessage("Given IBAN number has checksum ${calculateChecksum($value)} but it should be ${getActualChecksum($value)}");

@fracz
Copy link
Author

fracz commented Jan 5, 2018

How should that work? Where should I define the getActualChecksum and calculateChecksum methods so they are corretly resolved? They are not global. In the above example they have been imported to the file I defined the rules in, e.g. import {getActualChecksum} from "./iban-checksum". Writing the message as you suggested results in empty replacements, no errors in console.

@fracz
Copy link
Author

fracz commented Jan 5, 2018

Ok, you have pushed me into the right direction. You can pass the functions into the rule config, i.e.

ValidationRules
    .ensure('account').displayName("Account number")
    .satisfies(account => getActualChecksum(account) == calculateChecksum(account), {getActualChecksum, calculateChecksum})
    .withMessage("Given IBAN number has checksum ${$config.calculateChecksum($value)} but it should be ${$config.getActualChecksum($value)}");

and it works, indeed.

However, I think this is an abuse of what rule's config has been designed for.

And it does not solve the situation when an async function is used in satisfies and the backend responds with custom replacements. I mean: backend validation not only tells that the input is wrong but also what is wrong with it.

@ricardograca
Copy link

ricardograca commented Mar 1, 2019

Note that if the thing you're trying to compute dynamically is in the object the rules apply to you can use this:

.withMessage('Something or other: ${$object.thePropertyNeeded}')

@PetrMotlicek
Copy link

There should be something like $validationContext passed to any validation rule/function. Element, object, value, $config,... should be moved somehow under the $validationContext instance.

Then, $validationContext would be "the truest" place to get "a dynamic message" to be rendered, since it could be constructed by a validation function.

Now, the validation code works with arguments , instead of single argument in the form of $validationContext instance, extensible & configurable e.g. by a 'validation context factory'.

@Sayan751
Copy link
Member

FYI this requirement is addressed in Aurelia 2. In Aurelia 2 you can create your own custom rule class. This gives the encapsulation, as @PetrMotlicek suggests. Every rule has an execute method, which can be used to set any rule instance properties. In addition, the message template supports accessing the rule instance properties using $rule.property syntax. For more info, refer https://docs.aurelia.io/app-basics/validating-data.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants