henrikac
(Henrik Christensen)
1
Hi,
I have been searching in the documentation and all over Google all evening to find out how I would render form errors for individual form fields in Leaf - something like this
<form method="POST">
<input type="email" name="email"/>
#if(emailError):
<p>#(emailError)</p>
#endif
...
</form>
but so far not successful.
func register(req: Request) throws -> Response {
do {
try User.Create.validate(content: req)
} catch {
print(error) // <--- prints list of error messages
let context = ...
return try req.view.render("auth/signup.leaf", context)
}
...
}
this would be "okay" if I just wanted to just list the errors e.g. at the top of the form.
I hope that someone in this forum has a solution to this problem.
0xTim
(Tim)
2
Are you setting the emailError in the context in the catch?
henrikac
(Henrik Christensen)
3
It was my plan (unless there is a better way) but in the catch I am only able to get a list of error strings but not which field fails the validations.
0xTim
(Tim)
4
The validations library may not be the easiest thing to use for that use case, you might want to roll something manually in that case
henrikac
(Henrik Christensen)
5
Yeah, I was afraid you would say that 
I noticed that all error strings would start with the name of the failing field - e.g. "username is empty".
Would this be an okay way of doing it (only going to do something like this in this route)?
struct SignUpFormContext: Encodable {
var username: String?
var email: String?
var usernameError: String?
var emailError: String?
var passwordError: String?
}
func signupPostHandler(req: Request) async throws -> Response {
do {
try User.Create.validate(content: req)
} catch {
let data = try req.content.decode(User.Create.self)
var context = SignUpFormContext()
context.username = data.username
context.email = data.email
if let errors = error as? ValidationsError {
errors.failures.forEach { result in
if result.isFailure {
if let field = result.failureDescription?.components(separatedBy: " ").first {
switch field {
case "username":
context.usernameError = result.failureDescription
break
case "email":
context.emailError = result.failureDescription
break
case "password":
context.passwordError = result.failureDescription
break
default:
break
}
}
}
}
}
return try await req.view.render("auth/signup", context).encodeResponse(for: req)
}
...
}
0xTim
(Tim)
6
Yeah that's probably what I'd do
henrikac
(Henrik Christensen)
7
Really appreciate all the help.