Fork me on GitHub

anyone here who switched from to re-frame? or vice-versa? Sorry for the rant, but I don't understand why people claim 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 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?


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


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


Particularly if you can point the way to making it easier


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?


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


@mikethompson Sorry if it sounds like I'm complaining. My team decided to switch from 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.


@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


@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 (?)


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


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


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


@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.


@ag Indeed, the todomvc tries to show everything.


@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.


@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


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


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

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


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?


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


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


@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.


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


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


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


is it ok to dispatch from an effect?


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


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


@danielcompton ok cool, that's reassuring


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


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


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


(when not using the chrome devtools)


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


and variations of


but actually


I lean on re-frisk-remote much more


looks like this


allows inspection of events and db


@danieleneal your snippet is exactly what I was looking for


prn is the best debugger


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?


I believe you can use if you have some complex async workflow


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?


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


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 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).


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)


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


@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.


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


;; untested
(def some-common-ajax
    :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: