Fork me on GitHub
#re-frame
<
2018-08-29
>
bmaddy01:08:42

I'm trying to get re-frame, re-com, and re-posh working together (I'm new at all of these). I need to get some tab entities for my :horizontal-tabs re-com component. They need to look something like this:

[{:db/id 1 :item/name "foo"}
 {:db/id 2 :item/name "bar"}]
With Datomic, I'd just do a query like '[:find (pull ?e [:db/id :item/name]) ...] and get exactly what I need, but re-posh doesn't support pull expressions in queries. The directions on combining subscriptions here https://github.com/denistakeda/re-posh#combining-subscriptions show how to do it with a single entity, and the sample todo app shows how to loop through each entity and render a react component for each entity, but all I need for re-com is the data. Having functions to just manipulate data in the view seems like bad form. Is there a standard way of doing this?

bmaddy02:08:57

Hmm, it looks like I can make a normal re-frame/reg-sub subscription and use the signal graph, but then I don't have access to the datascript db unless I reach outside the function to get it. 🤔

steveb8n03:08:28

anyone else using Artemis with re-frame? I’m a bit new to both and following the sample app doesn’t seem very idiomatic for re-frame. I’m hoping to join forces with someone to work through a best practice for this integration @colindresj @yedi

myguidingstar11:08:13

is there any sample code of testing re-frame events? Something like init-db + list-of-events -> expected db + expected effects

manutter5111:08:45

For testing I typically do something like this:

(defn handle-toggle [db [_]]
  (update db :thing-to-toggle not))

(rf/reg-event-db
  :my/toggle
  handle-toggle)
That’s off the top of my head and I’m a bit caffeine deprived so hopefully that’s sane. But you get the idea: have a named fn to do the work of the event handler, then you just test the fn like anything else.

manutter5111:08:12

I should also add that for any handlers as simple as the above example, I generally don’t bother to write tests, since REPL-testing should flush out any significant bugs.

bmaddy17:08:04

Conveniently, re-posh uses a multimethod internally, so I was able to figure out a way to solve my problem:

(defmethod re-posh.subs/execute-sub :pull-many
  [{:keys [pattern ids]}]
  (reaction
   (mapv #(deref (p/pull @re-posh.db/store pattern %)) ids)))

(re-posh/reg-sub
   ::items
   :<- [::item-ids]
   (fn [item-ids _]
     {:type :pull-many
      :pattern '[:db/id :item/name]
      :ids item-ids}))
Yay! 😄

rspurrier17:08:00

just hopping in to say i finally get to use re-frame again for the first time in over a year. ITS GOOD TO BE BACK LETS GOOOOOOOO!

kasuko19:08:17

Has anyone used re-frame-async-flow-fx in a nested style? I'd like to refactor my applications boot process, however, I don't think I want everything in one flow. For example, in the top flow I'd like to treat authentication as just one "event" but inside my authentication system I'd like to manage it's complex states using it's own async-flow-fx ... just wondering if anyone has done this to some effect?

lwhorton20:08:34

its possible, but the simpler your auth flow the better

lwhorton20:08:53

it’s one of those things that’s easy to get wrong, lots of corner cases.. just nasty all around. especially if you’re doing MFA too.

rspurrier20:08:10

im not exactly sure of what you mean by 'nested style'. but i've used async-flow-fx before to handle rendering of some charts. the workflow is basically: start render. if render is success, push the resulting SVG. if rendering failed, push the error along. https://github.com/robert-spurrier/planisphere/blob/65c53f442c31143984aec33004670db55cd86c21/src/cljs/planisphere/events.cljs sorry if it is not useful for you!

kasuko18:08:59

Sorry, got super distracted, to get ready for async-flow I actually have to refactor a lot of other stuff. What I was referring to was to have one async-flow which is like the top level flow for app init (e.g. start -> initialize things -> authenticate -> fetch config -> done) and I wanted that "authenticate" step to be it's own seperate async-flow (e.g. start -> check local storage token -> fetch domains -> get user input -> attempt authenticate -> authenticate -> done)