Let's say I want to add a custom validation rule on a field of a signals form which is also validated by the email validator. But I want my custom validator to only run (or do its actual job) if the email is valid?
How would I do that?
I tried checking the errors of the field inside the validation logic, and also tried checking it inside an applyWhen condition, but thows two approaches lead to an error being thrown due to cyclic computations.
#signal forms: how to validate only if no other validation error
13 messages · Page 1 of 1 (latest)
How did you try to apply the condition and what was the exact error?
Would it be enough to run your custom validator when the field is generically valid, instead of checking a precise validator?
I'll post a repro when I have some time.
Here is a minimal repro: https://stackblitz.com/edit/stackblitz-starters-wn1ecdxb?file=src%2Fmain.ts
The error (visible in the console) is:
ERROR Error: Detected cycle in computations.
at Object.producerRecomputeValue (_effect-chunk.mjs:302:15)
at producerUpdateValueVersion (_effect-chunk.mjs:102:8)
at FieldNode.computed2 (_effect-chunk.mjs:271:5)
at main.ts:48:37
at signals.mjs:223:28
at _structure-chunk.mjs:19:14
at _structure-chunk.mjs:87:21
at Array.reduce (<anonymous>)
at _ArrayMergeIgnoreLogic.compute (_structure-chunk.mjs:86:21)
at FieldValidationState.syncErrors.ngDevMode.debugName [as computation] (_structure-chunk.mjs:619:53)
It doesn't surprise me, but I wonder if there is a way of conditionally applying/running a validator depending on the result of other ones, other than making the validator asynchronous.
What's not working in this simple change?
~~https://stackblitz.com/edit/stackblitz-starters-h1jsggqz?file=src%2Fmain.ts~~
ctx.state.errors.length is not checking for number of errors. errors is a signal, that isn't called, a typo i guess. Calling errors() leads to the cycle error
You're right.
I made that typo and checked the wrong way.
It's strange linter didn't notify of the error.
Oh right: signals are just functions, so they have the length property.
I did not play with signal forms myself yet. Still, I would try to build a custom validator that uses the provided emailvalidator inside to trigger the additional validations, and set that custom validator instead of the standard one on the form control.
That's what I did when the form was a reactive form. But the only thing that signal forms provide (AFAIK) is the email function (https://angular.dev/api/forms/signals/email) which applies the validator to a field, but can't be called to just check if something is an email or not.
Right, it is not obvious how to extend it now. The EMAIL_REGEXP is not exposed either 🤷♂️