badkins
2020-2-21 22:36:48

I’m getting ready to add “flash messages” to my web app. I think this is typically done by storing messages in the session, but they need to be automatically cleared. So that seems to imply that every return from a controller action (e.g. whether rendering a template or redirecting) will need to be involved so that the flash can be cleared since you won’t necessarily know ahead of time which page will display the flash message. Does that sound about right?


notjack
2020-2-21 23:53:07

What’s a flash message? (I am not up to date on web UI stuff)


badkins
2020-2-22 01:06:18

@notjack here’s a typical scenario: 1) user attempts to access an authenticated page, 2) they’re redirected to the login page /login?return_url=/original-page 3) after logging in, a “flash message” is set to “Login successful”, and they’re redirected to the original page, 4) the flash message is displayed in the view of the destination page


badkins
2020-2-22 01:06:52

basically, you want a message stored in the session to be viewed after a redirect, but then you want to remove it so the subsequent page doesn’t show it again


badkins
2020-2-22 01:08:50

So, “clearing the flash messages” amounts to sending a session cookie w/o the flash information which requires cooperation from all controller actions.


badkins
2020-2-22 01:11:34

I’m not too proud to post my ugly, work-in-progress scratch pad code, so here is the relevant part of the login action: (if user ; http or https (let ([ session-cookie (create-session-cookie (hash 'userid (user-id user) 'flash (hash 'notice "Login successful"))) ]) (redirect-to (return-url-or-default attrs "/") temporarily #:headers (map cookie->header (list session-cookie)))) (render-view login)))) the view @(let ([ notice (get-notice request) ]) (when notice @`{ <div class="info"> @,notice </div> })) the controller of the destination page (hard coded as an experiment) (define (clear-flash-headers) (let* ([ session (get-session request) ] [ cookie (create-session-cookie (hash-remove session 'flash)) ]) (map cookie->header (list cookie)))) (define (handle-get) (println (get-session request)) (render-view org-home (clear-flash-headers))) the helper (define (get-notice request) (let* ([ session (get-session request) ] [ flash (and session (hash-ref session 'flash #f)) ] [ notice (and flash (hash-ref flash 'notice #f)) ]) notice))


badkins
2020-2-22 01:12:14

The main challenge is to get all this done in a very elegant, user-friendly way.


badkins
2020-2-22 01:14:38

In Rails, about all you need is the following in the login action: flash[:info] = 'Login successful' and the following in the view: <% if flash[:info] -%> <%= flash[:info] %> <% end -%>


badkins
2020-2-22 01:14:54

Everything else is handled by the framework automatically.