Fork me on GitHub
#re-frame
<
2017-07-17
>
ag03:07:35

anyone here who switched from om.next to re-frame? or vice-versa? Sorry for the rant, but I don't understand why people claim om.next to be "hard" and re-frame to be simpler? I feel like it's complete opposite. I'm trying to understand all re-frame's event's, event handlers, subscriptions, effects, co-effects, interceptors, whole deal with the signal-graph etc. In my book is not simplicity. Or that's just my cognitive bias and re-frame really is simple and clean model as many describe it? I really feel that om.next although not easy to grok, in the long run makes things simpler. And I thought re-frame is easy but makes things complex over time. Thoughts?

mikethompson03:07:03

I won't comment on the comparison, but I'm alsways interested to know what people find hard to understand about re-frame

mikethompson03:07:45

So if you can provide any insight into what you are having trouble with, I'm all ears

mikethompson03:07:02

Particularly if you can point the way to making it easier

mikethompson03:07:39

I'm also slightly puzzled because you say re-frame "makes things complex over time" which seems to suggest you are well up the learning curve and have been using it for some time?

mikethompson03:07:15

So I'm wondering what complexities accumulate and, ideally, how that can be improved. @ag: ^^

ag04:07:23

@mikethompson Sorry if it sounds like I'm complaining. My team decided to switch from om.next to re-frame and one of the arguments was "because it's much simpler". I'm personally not finding it simpler to be honest. I can't point to anything specific - haven't acquired enough knowledge yet. Maybe it's just my bias and my own perception. Maybe after using Re-frame for a few months I would be able to reflect on differences.

mikethompson04:07:24

@ag Righto, I'll be interested to hear how you go and please feed back anything which gets in the way of the learning process

ag04:07:30

@mikethompson there's one thing I can possibly complain about at this point. I couldn't find anywhere generated api documentation for re-frame.core. Maybe because elements of re-frame have similar structure there's no need for it (?)

ag04:07:00

to be fair though the source code seems to be well documented.

mikethompson04:07:21

@ag That's a fair criticism. I'll correct that.

mikethompson04:07:16

FWIW, the API is fundamentally these 7 functions: dispatch subscribe reg-sub reg-event-fx and reg-event-db reg-fx reg-cofx But, as I said, I'll correct that

ag04:07:26

@mikethompson oh, wait, it's not just seven functions. Any newbie trying to read todo-mvc example almost immediately gets stumbled upon standard interceptors like after.

mikethompson05:07:30

@ag Indeed, the todomvc tries to show everything.

mikethompson07:07:54

@ag I deliberately use todomvc to show EVERYTHING in re-frame. Which is a bit much initially, I acknowledge. I'll think more about that. Perhaps I need a "light" version and then the "heavy" version. On the other hand, the simple example is a truly simple lead in to get people going. I'm hoping you found that useful and, er, simple. In the meantime, I've just spent a hour further improving the comments within todomvc. Checked in. I have to run now, so I'm slightly afraid I've broken something adding those comments, but I've no time to check until I get back. Please keep the comments coming. It is very valuable to get feedback about what works and what does not in the learning experience. I'll work on that API side of things a bit later also.

pesterhazy08:07:57

@mikethompson I've also noticed the lack of API docs. It's pretty easy to refer to the core ns to see what's public api, but a codox style single page with the public API would be a great addition

pesterhazy08:07:44

relatedly, I've been re-reading the docs/ and have bad a lot of fun in the process - truly some of the best out there

pesterhazy08:07:43

by the way, does dispatch guarantee order? So if I

(do (rf/dispatch [:reset]) (rf/dispatch [:set-foo :bar])))
that'll work?

pesterhazy08:07:53

Second question: let's say I want to encode all of my effects using reg-fx. Suppose I now want to dispatch effect :launch-missile. Is it true that I need the reg-fx and a (reg/event-fx :launch-missile (cosnstantly {:launch-missile nil})) in addition to that?

danielneal09:07:13

yes - I think that's right. And then in testing you can use a different reg-fx, that doesn't launch the missile, but your handler code stays the same

danielcompton09:07:18

@pesterhazy yep, dispatch guarantees order, dispatching adds events to a queue

danielneal09:07:24

@danielcompton I made a PR to reframe-async-flow-fx based on what @kennethkalmer and I were talking about the other day; how can you pass data from an event in the async-flow-fx chain to another event. I'm not sure if you'll think this is a good idea or not, or useful, but thought I'd put it up just in case.

danielcompton09:07:58

Thanks, I'll try to take a look sometime, but I may not get to it for at least the next 4 weeks or so

danielneal09:07:30

yeah no pressure, that will give me some time to try it out a bit more too, at the moment it is an idea that meets a need, but I need to figure out if it is actually worth it

pesterhazy09:07:03

@danieleneal I see. It's a bit of duplication but not too painful

pesterhazy09:07:19

is it ok to dispatch from an effect?

danielneal09:07:47

I do, but not sure if it's "right" 😬

danielneal09:07:37

hasn't caused me any problems so far though (fingers creossed)

pesterhazy09:07:17

@danielcompton ok cool, that's reassuring

pesterhazy10:07:35

is there a simple logging interceptor which prints out less information than rf/debug?

pesterhazy10:07:43

I'd like to log out only the events for example

pesterhazy10:07:58

on react-native, rf/debug is way too spammy

pesterhazy10:07:09

(when not using the chrome devtools)

danielneal10:07:09

(def debug-event
  (->interceptor
    :id :debug-event
    :before (fn [context]
              (prn (get-in context [:coeffects :event]))
              context)))

danielneal10:07:20

and variations of

danielneal10:07:04

but actually

danielneal10:07:10

I lean on re-frisk-remote much more

danielneal10:07:52

looks like this

danielneal10:07:11

allows inspection of events and db

pesterhazy10:07:47

@danieleneal your snippet is exactly what I was looking for

pesterhazy10:07:26

prn is the best debugger

pandeiro16:07:49

I'm wondering what is the typical pattern used for chaining ajax calls together now that there is reg-event-fx? Is it just a matter of dispatching another http fx event inside the success handler of the first http fx event? Or is there another pattern?

talgiat16:07:30

I believe you can use https://github.com/Day8/re-frame-async-flow-fx if you have some complex async workflow

talgiat17:07:08

We're currently in the process of upgrading from re-frame 0.7 to 0.9.4. We've been using re-frame for over two years and have a pretty big ClojureScript codebase (~20K LOC). The main difference I see in the way we use re-frame is our reliance on after (or before) middelwares for implementing event's side effects vs. the current best practice of using reg-event-fx and return a map of side effects. One disadvantage I see with the new approach is that the event logic is spread around multiple fx handlers as opposed to seeing everything in one place. It's also unclear now when would you use the after interceptor vs. fx handler, maybe after will be used if you want to control the order of side effects? Has anyone had similar issues migrating from pre 0.8 version?

imborge17:07:55

I'm working on an app utilizing WebRTC, is there anything wrong with storing the RTCPeerConnection object in the app-db?

akiroz17:07:46

Hmm.... I'm pretty sure the original argument from a few years back was comparing Om and reagent. Om's hard because it came with single atom state transactions and you build the DOM using functions for each element. I have not used Om.next so I can't comment on the matter but re-frame should be considered simple according to the clojure/rick hickey definition of the word. I would have to say that it definitely wasn't easy though (coming from a background without having used pedestal's interceptors).

akiroz17:07:52

In general, storing JS objects in the db is not a problem unless you need your db to be serializable. However, since RTCPeerConnection is one of those stateful "interface" objects that interact with native browser code, I would argue that they don't belong in the app-db (since it's not data). If you don't mind having a bit of OOP in your code then putting it in the app-db is completely fine. Otherwise you can write a functional wrapper that does all the RTC stuff (e.g. have a function that makes the connection and returns a string connection ID instead of an object)

shader19:07:44

is it possible to include more coeffects in an effect handler? I want to be able to load a session token from the app db before making a request via ajax

mikethompson22:07:02

@talgiat If I'm understanding you correctly, it sounds as if you were using middleware to factor out common code. That's still a very valid path, but now you use interceptors.

mikethompson22:07:34

These new interceptors can have an :after fn which adds to the :effects

mikethompson23:07:54

;; untested
(def some-common-ajax
  (->interceptor
    :id :common-ajax
    :after (fn [context]
             (let [db   (get-in context [:effects :db])]
               (assoc-in context [:effects :http-ajax]  ...])))))
BTW, some people miss the change log and it contains useful information about the changes you need to make 0.7 -> 0.8: https://github.com/Day8/re-frame/blob/master/CHANGES.md#080--20160819---the-walnuts-release