Fork me on GitHub

Does anyone write tests for re-frame applications? Are there any examples online?


you can use the re-frame template's +test option:


for cljs tests.


if you prefer clojure tests, and can afford to write your events/subscriptions in cljc, then you can test a lot of your re-frame app from clojure (on the jvm without selenium et al)


how to use reCaptcha in clojurescript for registration from?


@yenda I'm using Sente in my re-frame app, and I think also some other people here uses it. I don't like how they integrate though, so thinking about writing someting simpler myself


Question for the channel: how morally wrong is to have a let [something @(subscribe [:something])] inside a handler?


is this a view, sub or event?


@nilrecurring: Can you elaborate on why you want to do that? The common advice as far as I remember is not to subscribe within a handler, and I've never found it necessary, but I can't remember exactly why it's recommended against at the moment. Depending on what you need, there may be another way to accomplish the same goal without having to use a subscription.


@shaun-mahood I think it's not recommended because the subscription gets created and stays there, eventually leaking memory? Not sure though, just guessing.


Elaborating a bit more on what I'm doing: basically I have a fairly complicated subscription - let's call it :foo- that takes three other subscriptions, does stuff and returns a result. It's around 20 lines long, definitely not trivial.


I created it because I needed to display it in a view.


Now, in this other use case I dispatch an event with some parameters, I subscribe to :foo, and I do stuff with the parameters, eventually dispatching again


This is one possible solution, the other solution would be to subscribe to :foo in the view from which I'm dispatching, and pass it in the event vector


So there is another way, but I'm asking about being idiomatic and about possible downsides


Personally, I'd go with the latter simply because events aren't reactive signals


@nilrecurring: Idiomatic would be to avoid subscribing in an event as far as I know, hopefully someone else can answer the downsides question - but if you go back in the slack archives I'm pretty sure it has been discussed in the last 2 or 3 weeks, I just can't remember the details


Thanks! Unfortunately slack has already cut the history 😞


Would this be a topic worth of a paragraph in the docs?


So that if the question gets asked again we have it in the FAQ


sounds like a good idea to me 🙂


@nilrecurring: Check out the archive at - if you come up with anything, it would be awesome if you could do a PR to the FAQs section as it's definitely come up more than once.


Follow-up question: but what if I'm in a chain of 4-5 dispatches and it's just unconvenient to pass the value in from the view?


(I'm in this situation right now)


maybe put the computation in a plain function that reduces the app-db into what you want and call it in both the sub and event?


@akiroz yes, this is a valid option too


But a subscription is already doing that, so until it's necessary I would avoid unnecessary decoupling


@nilrecurring: Do you mean a chain of 4-5 subscriptions rather than dispatches?


@shaun-mahood dispatches: from reg-sub-fx you can dispatch (and dispatch-n) more events, and create 'chains' of dispatches


So in this case I have button presses that send ajax calls, stuff happens to the db, and then at some point I need the value created by the :foo subscription


@nilrecurring: Ok, wanted to make sure before I answered - there are different issues with chaining dispatches vs. chaining subscriptions.


In that case, I would probably look and see if adding an interceptor and your own fx-handler to add the value you need to your cofx. You could then carry it through the context of the whole chain of events pretty easily - it may not solve the question of what you do with the subscription, but at least it would make it consistent for how to refer to that value from any one of the chains, and might make it more convenient to pass the value in from your view.


It took me a while to wrap my head around the fx/cofx/interceptors and figure out how I could use them, but now that I've done it a few times I'm a huge fan of how well it reduces decoupling, especially for things like ajax calls and returns. I've used them in a few places where I would have had a chain of interceptors in the past and it's enabled me to create just one interceptor, though that's won't be the case for all situations.


Does anyone know of a set of steps for migrating a reagent app to re-frame?


i started this app before i’d come across re-frame and dearly wish now that it hadn’t been the case


i’m not sure if it’s relatively simple or if i should create a new re-frame app and starting migrating things across (which has its own bugbears)


@sandbags Well, re-frame is really just a library you can together with reagent to manage state and events. It depends on how you're currently dealing with these things in your current app. I've done this once myself, I created a new project following re-frame directery structures and reused nearly all of the reagent components with minor changes.


any gotchas? i’m mainly concerned about spending hours fixing bugs because i missed some step or other


i’m inclined towards starting a new re-frame app and doing a c/p job to merge useful parts (e.g. components) of the old app in


would also give me a chance to clean some of it up


but that’s a bigger undertaking


at least, up front


I haven't really had any problems with the migration since I basically just threw all the r/atoms into the app-db and chopped up each component into view/sub/event


@danielcompton super cool, thanks! So doing the @(subscribe thing has no issue (apart from being ugly) since subs are deduped in 0.8


Yeah I guess. It still feels a bit like you're crossing the streams, as the re-frame data cycle is

app-db -> subs -> render -> events -->|
   ^ ----------------------------------


I think there's probably a more elegant way for re-frame to provide to do this, but what you've got should work ok


Read #218 as well if you haven't already


I read #218 some time ago, happy to see there are some new comments