Add validation rules to primitives

I have just ran into a case where I need to validate plain strings which are not a named property of an object but elements of an array.

I have tried roughly the following code, but it does not seem to work:

this._optionRules = ValidationRules
    .ensure((o: string) => o.length).min(1).withMessage(requiredMessage)
    .rules;
<li repeat.for="option of options"> <!-- options: string[] -->
    <custom-input value.bind="options[$index] & validate:_optionRules"></custom-input> <!-- wrapper for html input -->
</li>

Note that:

  • binding the option object directly does not work at all (since it is a primitive I assume it does not get propagated correctly)
  • a simple .ensure(o=>o).required() does not work either since the parser fails.

not sure about the validation…
but regardless - you should bind to the repeated item instead of arr[$index]
so
value.bind="options[$index] & validate:_optionRules"
is better as value.bind="option & validate:_optionRules"

@m-gallesio At this point there is no validation API provided to validate a collection. And that is what I believe you need for your case.

Having said that an easy workaround is to write a custom validation rule (using a lambda), and use it with .ensure('options').satisfies(your_lambda_that_validates_the_options_array). In fact a quick and dirty version might look like this:

.ensure('options')
.satisfies(options => options.every(item => !!item))

You can see an example of this here: https://gist.dumber.app/?gist=03142be98f1632d71e5a93166e19877d.

You can see that there is one validation message for the whole collection of items. If that does not suite your purpose, another workaround can be to create custom element that is bound of one item of the options array, and implements the validation rule for the single bound string. That way you can have validation message for every missing value. However, in reality that might result in a too crowded UI.

@avrahamcool I have tried that, but the binding does not get propagated back to the original collection. This could be a problem with our custom component.

@Sayan751 I had not thought about the problem in this way, but technically our use case is indeed making sure every item in a collection is filled in. I have noticed in the past that this kind of validation clashes with how we handle the visual rendering of the validation result and might not be feasible, but I might look into it.

For now I have handled this issue with just a validation in the backend, which is slightly suboptimal for the user, but thank you for your input anyways.

maybe you forgot to declare the default binding mode as twoWay?

It already is twoWay, so this is not the problem; however my version works as intended.
I do not have time right now but I might try to built a basic reprodution.

1 Like