Rendering leaf form errors

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.

Are you setting the emailError in the context in the catch?

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.

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

Yeah, I was afraid you would say that :sweat_smile:

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)
    }

    ...
}

Yeah that's probably what I'd do

Really appreciate all the help.