@@ -99,7 +99,18 @@ For this, we use Hunchentoot's life cycle and CLOS-orientation:
99
99
(ht:delete-session-value :flash))
100
100
```
101
101
102
- which means: after we have handled the current request, delete the ` :flash ` object from the session.
102
+ which means: after we have handled a request, delete the
103
+ ` :flash ` object from the session.
104
+
105
+ {{% notice warning %}}
106
+
107
+ If your application sends API requests in JavaScript, they can delete flash messages without you noticing. Read more below.
108
+
109
+ An external API request (from the command line for example) is not
110
+ concerned, as it doesn't carry Hunchentoot session cookies.
111
+
112
+ {{% /notice %}}
113
+
103
114
104
115
## Render flash messages in templates
105
116
@@ -269,3 +280,45 @@ you'll see a flash message, that is deleted after use.
269
280
Refresh the page, and you won't see the flash message again.
270
281
271
282
- full code: https://github.com/web-apps-in-lisp/web-apps-in-lisp.github.io/blob/master/content/building-blocks/flash-messages.lisp
283
+
284
+ ## Discussing: Flash messages and API calls
285
+
286
+ Our ` :after ` method on the Hunchentoot request lifecycle will delete
287
+ flash messages for any request that carries the session cookies. If
288
+ your application makes API calls, you can use the Fetch method with
289
+ the ` {credentials: "omit"} ` parameter:
290
+
291
+ ~~~ javascript
292
+ fetch (" http://localhost:9876/api/" , {
293
+ credentials: " omit"
294
+ })
295
+ ~~~
296
+
297
+ Otherwise, don't use this ` :after ` method and delete flash messages
298
+ explicitely in your non-API routes.
299
+
300
+ We could use a macro shortcut for this:
301
+
302
+
303
+ ~~~ lisp
304
+ (defmacro with-flash-messages ((messages) &body body)
305
+ `(let ((,messages (ht:session-value :flash)))
306
+ (prog1
307
+ (progn
308
+ ,@body)
309
+ (ht:delete-session-value :flash))))
310
+ ~~~
311
+
312
+ Use it like this:
313
+
314
+ ~~~ lisp
315
+ (easy-routes:defroute flash-route ("/flash/" :method :get) ()
316
+ (with-flash-messages (messages)
317
+ (djula:render-template* *flash-template* nil
318
+ :flashes (or messages
319
+ (list (cons "is-primary" "No more flash messages were found in the session. This is a default notification."))))))
320
+ ~~~
321
+
322
+ We want our macro to return the result of ` djula:render-template* ` ,
323
+ and * not* the result of ` ht:delete-session-value ` , that is nil, hence
324
+ the "prog1/ progn" dance.
0 commit comments