Fork me on GitHub
#re-frame
<
2017-12-13
>
jacekschae07:12:11

Shameless plug 😅 check out conduit https://github.com/jacekschae/conduit most events manage call to server and based on success or failure update app state

mikerod14:12:51

People on here (including me) have asked for some real examples of re-frame apps that are open source to take a look at. I just found this one https://github.com/district0x/ethlance

mikerod14:12:04

I believe that district0x has perhaps 1 or 2 more in their github org too

mikerod14:12:10

it’s quite a large example though

mikerod14:12:53

@jacek.schae Nice. This this conduit impl looks interesting to read through.

jacekschae15:12:09

@mikerod it's heavily inspired by todomvc example when it comes to comments/structure. There is also API spec that could help you understand what we get from the server https://github.com/gothinkster/realworld/tree/master/api

mikerod15:12:54

@jaceklach thanks. Yeah I’m familiar with this server spec. Inspiration from the commenting from the todo is a good choice too!

damian16:12:13

https://github.com/bbatsov/clojure-style-guide#documentation This is the convention to document clojure functions. Is there an idiomatic way to do the same for re-frame handlers?

mikerod16:12:19

@p-himik perhaps you can’t have :value = nil on an :input ?

p-himik16:12:05

@mikerod I think you can - I use it all the time.

mikerod16:12:50

maybe that? I don’t know though, just throwing some thoughts out there 😛

mikerod16:12:07

I thought I had an issue with setting a :value nil before on an :input, but I don’t remember anything specific

p-himik16:12:26

Ah, thanks! That link makes sense.

mattly17:12:14

is there a reason that (rf/reg-sub ::state ::state) will, when subscribed to, return [::state] instead of the result of (::state db) ? I thought I’d take a nice shortcut over (fn [db] (::state db)) but it seems re-frame is being clever

mattly17:12:58

hm, perhaps it’s mistaking what I’m doing for the :<- syntax sugar

mattly17:12:21

I get the same behavior with (rf/reg-sub ::state (partial ::state)) as well

mattly17:12:33

it has to be (rf/reg-sub ::state (fn [db] (::state db))

mikerod17:12:35

@mattly I think it’s because your db doesn’t have that key?

mikerod17:12:45

re-frame is really passing 2 args

mikerod17:12:58

(fn [db qvec] (::state db))

mikerod17:12:09

so when you shorten, I think you end up doing (::state db qvec)

mikerod17:12:41

So db has no entry for ::state key and it is returning the qvec as the “return when missing” value to calling the keyword as a fn

mikerod17:12:11

the qvec for your subscription is just [::state] since you aren’t passing query args and the first item in the query vector is the name of the subscription itself - ::state here

mattly19:12:41

yeah you’re right I forgot about the extra arg since js doesn’t enforce arity

mattly19:12:45

(rf/reg-sub ::state (comp ::state (partial apply first))) works as well but I may as well use the anon fn at that point

mikerod19:12:32

> but I may as well use the anon fn at that point Yep, hah

mikerod19:12:34

No problem

mikerod19:12:03

@mattly after writing long-hand subscription and event handlers for a while, I ended up just making a few macros

mikerod19:12:17

There is also a lib or 2 that define some.

mattly19:12:36

I’ve used a generalized :get-in subscription in the past

mikerod19:12:58

you could do that too, but that has some caveats on the reactivity of the subscription

mattly19:12:59

but that encouraged some bad patterns

mikerod19:12:10

(e.g. everything watching the top db level for changes, etc)

mikerod19:12:26

a macro you can make expand out to something that isn’t problematic

mikerod19:12:34

then again, I know it is nice to avoid macros at times

mikerod19:12:10

I didn’t write a macro for a get-in sort of thing. I ended up feeling the need for them more for subscriptions that have query vec arguments passed in that also are have other subscriptions as signals

mikerod19:12:16

that can get a bit messy and verbose

mattly19:12:17

a pattern I’ve been inching towards is for each namespace storing their stuff inside ::data and then helpers around subscribing to that

mattly19:12:01

btw, I’m giving a talk on re-frame at our local clojure group on the 4th of Jan: https://www.meetup.com/clojure-pdx/events/245270782/

mikerod19:12:19

This sort of thing is what I meant:

(rf/reg-sub
:mine/mine
(fn [[_ x y]]
  (rf/subscribe [:mine/something x y]))
 (fn [something [_ x y]] (do-stuff something x y))

mikerod19:12:44

I guess you can use rf/reg-sub-raw to cut down boilerplate on those too, but I still wanted to macro away the boilerplate over reg-sub-raw in this case 😛

mattly19:12:14

I’ve tried to resist writing my own little dsl around creating subscriptions & event handlers since that’s never worked out well for me in other areas

mikerod19:12:19

> btw, I’m giving a talk on re-frame at our local clojure group on the 4th of Jan Nice. I’m not in the Portland area. But cool you are giving a talk on re-frame . I fairly recently switched over an app that was only reagent to re-frame. I’m also in the progress of a brand new app that is starting with re-frame. I’ve definitely become a fan of re-frame now.

mikerod19:12:45

> I’ve tried to resist writing my own little dsl So did I, but then I gave in… Perhaps bad choice. Remains to be seen. 😛

Bravi21:12:49

Hi everyone. can you guys help me refactor my app a bit please? So basically I have a little application that needs to poll a few different APIs every x (let’s say 4) seconds. So I created this tick event

(defn- get-events-to-run [section]
  (when-not (:waiting-for-data section)
    (:ticker-event section)))

(re-frame/reg-event-db
 ::initialize-db
 (fn  [_ _]
   db/default-db))

(re-frame/reg-event-fx
 ::initialize
 (fn [cofx _]
   {:dispatch-n [[::initialize-db] [::tick]]}))

(re-frame/reg-event-fx
 ::tick
 (fn [cofx _]
   (let [events (->> (map (:db cofx) [:accounts :balances :orders])
                     (map get-events-to-run)
                     (remove nil?)
                     (into []))]
     {:dispatch-n (if (empty? events) [] [events])
      :dispatch-later [{:ms 4000
                        :dispatch [::tick]}]})))
It uses dispatch-later on itself and it basically checks, whether accounts, balances and orders are waiting for data (sometimes API calls may take more than 4 seconds) and if so, it excludes them from polling. And then for each section that is not waiting for data, it runs whatever is in ticker-event, which is the name of the event that should be run basically. For example get-account-balances or get-orders. But I have a feeling that I’m not dealing with this right and there’s a better option out there 😄

nberger22:12:30

A bit late to the party but here's another re-frame open source app: https://github.com/lambdaclass/holiday_ping (re-frame code is under directory priv/ui)