Skip to content

Instantly share code, notes, and snippets.

@hxegon
Last active March 11, 2023 17:14
Show Gist options
  • Save hxegon/1a1084f2c7df2cd4e2a5a2e1c8ce286b to your computer and use it in GitHub Desktop.
Save hxegon/1a1084f2c7df2cd4e2a5a2e1c8ce286b to your computer and use it in GitHub Desktop.
re-frame event loosely mimicking clojure 1.11's iteration
;; recur-event - dispatch vector for when target isn't reached
;; :root-path - Where is this iteration state to be kept in the app-db?
;; :unwrap - pre process step-ret. Identity by default. Example: parse json and get body key of response
;; unwrap output is input for nextf, reachedp, updatef, somep
;; :somep - Are there more items in this request? If not, consider this to be the end of available items
;; :nextf - Get next cursor value
;; :updatef - Update values - takes old values and output of unwrap, update iteration values in app-db
;; :reachedp - Did the cursor reach the desired item? passed ret val of nextf, is nextf by default
(rf/reg-event-fx
::iteration
(fn [{:keys [db]} [_ recur-event opts step-ret]]
(let [{:keys [nextf updatef unwrapf somep reachedp root-path]
:or {unwrapf identity somep identity reachedp nextf}}
opts
stepv (unwrapf step-ret)
nextv (nextf stepv)
more? (somep stepv)
next-db (if more?
;; Values exist
(-> db
(assoc-in (conj root-path :next) nextv)
(update-in (conj root-path :values) updatef stepv))
;; Values absent
(assoc-in db (conj root-path :terminated?) true))]
(cond-> {:db next-db}
(and more? (reachedp nextv))
(assoc :dispatch recur-event)))))
;; Example of this being used on a pathom endpoint
(re-frame/reg-event-fx
::get-gallery-image
(fn [{:keys [_db]} [event gallery-id image-id]]
{:request {:name event
:params {:context {:gallery/id gallery-id}
:query ['({:gallery/images [:filepath]} {:cursor cursor})
:gallery/images-cursor]}
:on-success [::iter/iteration
[event gallery-id image-id]
{:root-path [:galleries gallery-id :iteration]
:nextf :gallery/images-cursor
:updatef into
:somep (comp empty? :gallery/images)
:reachedp #(< image-id %)}]
:on-failure [::get-gallery-images-failure]}}))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment