Group Group Group Group Group Group Group Group Group

Show alert when redirect with vapor and leaf

Hi,

I have a form for user to subscribe to news letter, all it does is collect email and then return to the home page but I want to show alert on the homepage that the process was a success or failure. All I can come up with is using context and #if tag but how do I inject context with redirect(:to)

Here is my POST function

   func createHandler(_ req: Request) throws -> Future<Response> {
        return try req.content.decode(SubscribeEmail.self).flatMap(to: Response.self) { email in
            return email.save(on: req).map(to: Response.self) { email  in
                guard email.id != nil else {
                    throw Abort(.internalServerError)
                }
                return req.redirect(to: "/")
            }
        }
    }

And here is my form:

<form action="/api/email-list" method="POST" class="mr-4 mb-3 mb-md-0">
                    <div class="input-group input-group-rounded">
                        <input class="form-control form-control-sm bg-light" placeholder="Email Address" name="email" id="email" type="text">
                        <span class="input-group-append">
                            <button class="btn btn-light text-color-dark" type="submit"><strong>GO!</strong></button>
                        </span>
                    </div>
                </form>

@mannguyen you could use a query item in the URL which you can pick up in your request handler, similar to how the login failed warning is shown in the book

1 Like

Thank you. I was able to follow the login failed warning in the book to achieved what I want. However, that was only for when it failed. But when it success how would you handle the alert. Because right now if in the context i just set the error to false and in my leaf template I listen to if error false show success and if error is true show failure alert. Then my success alert would show 100% of the time.

You can have a success bool in your context that is set if a flag is set in the query, basically the opposite of what you do for error. There’s no reason you can’t do both

1 Like

right silly me I can just add another tag. Thank you!
Here is my code incase anyone need it

func homeHandler(_ req: Request) throws -> Future<View> {
        let context: HomeContext
        if req.query[Bool.self, at: "error"] != nil {
            context = HomeContext(emailSubsError: true)
        } else if req.query[Bool.self, at: "success"] != nil {
            context = HomeContext(emailSubsSuccess: true)
        } else {
            context = HomeContext()
        }
        return try req.view().render("home", context)
    }

struct HomeContext: Encodable {
    let title: String = "Home Page"
    let emailSubsError: Bool
    let emailSubsSuccess: Bool
    
    init(emailSubsError: Bool = false, emailSubsSuccess: Bool = false) {
        self.emailSubsError = emailSubsError
        self.emailSubsSuccess = emailSubsSuccess
    }
}

and then in the leaf template i just use if tag to check for emailSubsError and emailSubsSuccess