Fork me on GitHub
#re-frame
<
2018-02-28
>
caleb.macdonaldblack05:02:39

Can you define an event with just a chain of interceptors and no handler?

mikethompson06:02:16

@caleb.macdonaldblack No, but you can create a do-nothing handler:

(reg-event-db 
    :event-id 
    [a long list of interceptors]
   (fn [db _] db))      ;; <--- dummy, do nothing  handler ???

mikethompson06:02:54

Actually, better to do this:

(reg-event-ctx       ;; <-- rarely used event registration mechanism
    :event-id 
   [a long list of interceptors]
   identity)         ;;  <-- just return the `context` given 

caleb.macdonaldblack06:02:57

Thanks, that’s exactly what we were looking for.

gklijs09:02:42

You can also use the reg-event-fx might be more idiomatic.

mikethompson23:02:02

@U26FJ5FDM Use of reg-event-ctx is perfectly idiomatic, just rare.

kishanov06:02:09

shameless plug: I’ve written an article (https://medium.com/@kirill.ishanov/building-forms-with-re-frame-and-clojure-spec-6cf1df8a114d) and a corresponding sample application (https://kishanov.github.io/re-frame-spec-forms-example) about building forms using re-frame and clojure.spec (no frameworks have been created)

gadfly36108:02:54

@kishanov thanks for sharing, excited to read this!

erwinrooijakkers13:02:23

I have some db event handlers that do something stateful like this:

(re-frame/reg-event-db
  :db/initialize-iota
  (fn [db [_ v]]
    (let [state (make-state)]
      (assoc db :state state))))


(re-frame/reg-event-db
 :db/initialize-iota-mam
 (fn [{:keys [state] :as db} _]
   (let [changed-state (change-state state)]
     (stateful-fn changed-state)
     (assoc db :state changed-state)))
Is there a better way to code this? E.g., using another type of handler or an interceptor?

mikerod14:02:22

The example confuses me. It looks like the state is always passed along on the db, so why make it anything other than immutable data?

mikerod14:02:33

If all you are worried about is a “side effecting” behavior from stateful-fn, then what i think you are looking for is to use re-frames reg-fx - ie registering an effect handler

dimovich18:02:28

sth like this maybe?

danielcompton20:02:17

yep, you want to register your side effecting function as an fx handler that takes pure data and does the side effecting function

cjsauer16:02:06

@kishanov good read. I'm having a little bit of trouble understanding this paragraph though: >I’ve played with the idea of mapping error messages to s/explain-data while parsing the returned data structure and mapping error messages to different bits of this data structure, but I quickly abandoned this idea cause the resulting code is coupled to spec implementation itself and in real world it’s easier to have a custom error component that is mapped to predicate directly, rather then carrying the complexity of this data analysis to forms controller. I've also used s/explain-data in this way, and it allowed me to map specs to error messages, like this:

(def spec-err-msgs
  { :user/email "Invalid email provided"
    :user/name-length "Username must be between...characters long"
    ...})
In your example, I might have tried extracting some kind of :asn/monotonic-increasing-range spec, which checks that the ranges are ordered properly. That would let you hang error messages on that spec as above. I've also written and rewritten my form logic 5 times hehe. Interested in getting your clarification.

cjsauer17:02:10

I should also include: I had written an interceptor that ran s/explain-data on every input change, and stored it in app-db, so my spec outputs were alongside the values in app-db. These error messages could then be set up as subscriptions.

kishanov17:02:36

@cjsauer I’m mostly concerned about the problem of granularity of the error message. Imagine having a spec for password field (our beloved “1 upper case letter, 1 lower case letter, 8 charachters or more, etc.“). It’s easy to have 1 spec which will either have a regex to validate it or will use s/and and s/or to concat multiple specs. I’ve looked at how s/explain-data works for these these specs with conditional branching and didn’t like the complexity of mapping proper error message to each part of the branch

kishanov17:02:58

I’m not saying it’s impossible to do it, but it looks like unnecessary complexity to me. after starting to use spec I’ve noticed that the an attempt to have a perfect validation logic in the spec is an excellent way to procrastinate and not proceed with the actual work 🙂

cjsauer15:03:15

This makes perfect sense. I have definitely spent many hours tweaking specs to get that "perfect" combination haha. I put together a really tiny gist of what I've tried in the past. Instead of following the branches of the explain-data output, I opted to just always grab the last spec in the :problems vector. https://gist.github.com/cjsauer/10735e7a93af7d4eb1ff9f39b2fc5eea

cjsauer15:03:19

Doing this had the interesting side-effect of "spreading out" my spec definitions. Meaning all of the parameters passed to s/and were now spec keywords themselves.

hoopes17:02:30

hi, i have a dumb question that i can't seem to find via googling - how do i make a regular link work in re-frame? [:a {:href "" :target "_self"} "GOOGLE"] routes me to / in my router.cljs ... :target "_blank" opens in another tab. if i missed something obvious, i apologize in advance

hoopes17:02:02

i started from the re-frame template, fwiw

hoopes18:02:11

[re-com/hyperlink-href
   :label "go to google"
   :target "_self"
   :href ""]
does the same thing

hoopes18:02:22

welp! i'm not sure what i did, but it fixed itself - sorry for the noise. (i stuck with the re-com method)

leira20:02:35

a late thanks to @mikerod and @ivanreese

Ryan Radomski23:02:39

Is anybody using devcards with re-frame? Do the two even fit together nicely?

Ryan Radomski23:02:54

This is the nicest I've seen