Skip to content

Instantly share code, notes, and snippets.

@ericnormand
Last active September 9, 2019 02:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ericnormand/9a1fa763a44c4f1b957abd058ecf20ac to your computer and use it in GitHub Desktop.
Save ericnormand/9a1fa763a44c4f1b957abd058ecf20ac to your computer and use it in GitHub Desktop.

ajax state problem

AJAX calls in ClojureScript go through a lifecycle. They are placed, they're in flight, then they either succeed or fail. We often want to show this state to the user. For instance, when the ajax request is in flight, we want to show a loading spinner.

Create a representation of the state of a value that can be fetched via ajax. I suggest using the variant entity or the variant tuple. It may help to draw out the sequence diagram of an ajax request to capture all the states it may be in. Be sure to define the operations on this representation which transition it from one state to the next.

If you want some inspiration, Kris Jenkins has a neat post about modeling remote data. I've also written up two ways of approaching ajax state here.

;; Here are two examples of the three states it can be in
;; before the value is loaded
nil
;; once the value has been loaded
{:status :stable
:value true}
;; while the value is loading. We have to remember the old value in case it fails.
{:status :loading
:value false
:old-value true}
(defn begin-load [state next-value]
(cond
(nil? state)
{:status :loading
:value next-value
:old-value nil}
(= :stable (:status state))
{:status :loading
:value next-value
:old-value (:value state)}
(= :loading (:status state))
(assoc state :value next-value)))
(defn succeed-load [state]
(cond
(nil? state)
state
(= :stable (:status state))
state
(= :loading (:status state))
{:status :stable
:value (:value state)}))
(defn fail-load [state]
(cond
(nil? state)
state
(= :stable (:status state))
state
(= :loading (:status state))
{:status :stable
:value (:old-value state)}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment