Fork me on GitHub
#re-frame
<
2016-12-19
>
michaelstalker00:12:08

How difficult is it to add re-frame to an existing Reagent app?

michaelstalker00:12:35

I'm about to start a new app, and don't need a lot of state management right away. I'm thinking it may be quicker to get a Reagent app up and running.

michaelstalker00:12:47

...and then add re-frame later.

michaelstalker00:12:50

(Forgive the question if people ask this often! I'm new to the channel.)

gadfly36100:12:31

@michaelstalker as a heavy vanilla reagent user, i think it is hard to retrofit an existing app with re-frame

michaelstalker00:12:43

What are some considerations I should think about when deciding whether to go with vanilla Reagent or re-frame?

mikethompson00:12:22

The bigger your app, the more you'll need something like re-frame

mikethompson00:12:36

The smaller your app the less you need the structure it brings

michaelstalker00:12:20

That makes good sense.

mikethompson00:12:14

But if your goal is to learn interesting things, then re-frame might be useful at small scale too

mikethompson00:12:32

But it does represent early cognitive overhead

michaelstalker00:12:32

We use React/Redux at work. From the [admittedly little] reading I've done, re-frame is similar.

michaelstalker00:12:56

If that's the case, I've done my fair share of working through some of the cognitive overload already 🙂

michaelstalker00:12:10

I'm sure they're not identical, and that I'd still need to learn some new things.

mikethompson00:12:36

Yes, in that case, you'll find re-frame fairly natural. Although it is different in many aspects

mikethompson00:12:06

I have a passing knowledge of it :-)

mikethompson00:12:53

You'll prefer re-frame

danielcompton00:12:58

Just don't say that re-frame is inspired by redux, that's a sore spot 😛 (and re-frame was first)

michaelstalker01:12:43

How difficult is it to make a re-frame app isomorphic? We do that at work with JavaScript, and I've only started looking into how to do the same with ClojureScript.

michaelstalker01:12:59

I'm not actually sure that's a requirement for me. I'm just exploring my options at this point.

mikethompson01:12:33

What server side tech do you use?

mikethompson01:12:48

Clojure, Node?

mikethompson01:12:49

@danielcompton I've changed the README. It is the equivalent of racing around urinating on the boundaries. Woof :-)

mikethompson01:12:34

Let there be no mistake any longer :-)

mikethompson01:12:44

i feel better now

michaelstalker01:12:05

I haven't chosen a server-side tech, yet.

michaelstalker01:12:18

I was leaning towards Clojure.

cmal01:12:46

We use clojure for the server side. Is it better for us to use clojurescript instead of javascript for the front end project?

mikethompson01:12:34

If you use Node there is already a isomorphic solution, although I'm not sure how much it is used, so while functional, I'm not sure I could recomend it as a production solution (it might be, I just can't be sure)

mikethompson01:12:38

There are ways to do something similar on a Coljure backend, but you have to be a little skilled. It isn't packaged up.

mikethompson01:12:12

The problem on the JVM is that Reagent and React are javascript, and can't run on the JVM

mikethompson01:12:53

So you have to "render" to hiccup and then use another library to turn the hiccup into HTML.

mikethompson01:12:03

Doable, but not made into a library yet

danielcompton01:12:39

Nice to stake your claim 🙂

michaelstalker01:12:20

@danielcompton I wasn't sure if you were talking to me or @mikethompson. I'm not sure I'm up to that task, yet!

mikethompson01:12:15

I corrected the link above to External Resources

mikethompson01:12:28

@cmal too hard to say. If you are interested in Node, you might be interested in @yogthos new project called Macchiato http://yogthos.net/posts/2016-11-30-Macchiato.html

mikethompson01:12:52

He does good stuff

cmal01:12:16

Thank you for your advice! @mikethompson

mikethompson01:12:14

In theory, if you use Macchiato, you can swap backwards and forwards. Although it might be too early to make those claims too strongly just yet. Early days.

yogthos01:12:41

in theory it should be mostly compliant with ring core, only middleware I recall having to change api for was the multipart params

yogthos01:12:35

I think the ease of jumping between macchiato and ring will largely depend on what third party libraries you rely on

yogthos01:12:11

also the usual disclaimer that it's still pretty early days, and there could be some bugs 🙂

yogthos01:12:52

I've used it for a couple of small projects, and a few other people have started using it without any show stoppers so far

yogthos01:12:15

we have a #macchiato channel to discuss issues/ideas now

yogthos01:12:53

I guess another point worth noting is that macchiato is only complaint with ring async handlers

stuartrexking04:12:48

@mikethompson Do you have a preferred way of doing URL routing in re-frame?

stuartrexking04:12:14

Loving the new docs btw.

stuartrexking04:12:47

I see the todomvc uses secretary

stuartrexking04:12:56

I’ll look at that...

Drew Verlee05:12:15

So eager to jump right into my first toy re-frame full-stack application i did some searching and thought that using this would be the best way to get started: lein new luminus vending_machine +re-frame +datomic +cider sadly i hit an unexpected error right away: ‘lien uberjar`…

Compiling "target/cljsbuild/public/js/app.js" failed.
Exception in thread "main" java.lang.NoSuchMethodError: com.google.common.base.CharMatcher.javaUpperCase()Lcom/google/common/base/CharMatcher;, compiling:(/private/var/folders/qx/mn5d4sjn7w5b4fxs2l15lzk80000gn/T/form-init612906228494054095.clj:1:124)
So someone is looking for a method and it isn’t defined. But i’m not sure who and why.I did some searching and all i could find was people talking about dependency problems. So i tried to track that down.. lein deps :tree and i get about 50 lines of "Possibly confusing dependencies found:” with recommendations on how to do exclusions, none of which i’m sure will help. Any suggestions on maybe a better course of action in general or for tackling this specific problem? (not sure where to ask this type of question)

mikethompson05:12:25

@drewverlee Best to ask in the luminus channel, I think @stuartrexking there was no deep knowledge in that decision

Drew Verlee05:12:18

@mikethompson, in general, do you know of any other ways to get started building a re-frame datomic app then luminus? I suppose i dont see much else out there. But im a newbie in this community.

mikethompson05:12:26

I'm afraid I don't have much direct experience with Datomic

mikethompson05:12:56

luminus is normally pretty good

mikethompson05:12:37

Perhaps ask on the datomic channel?

mikethompson05:12:00

Sorry to keep encouraging you somewhere else

mikethompson05:12:58

If you just want to fiddle with the Client part then the re-frame-template certainly works

mikethompson05:12:07

(but no server part)

martinklepsch06:12:59

@mikethompson hey 🙂 while you're here would you mind replying to the last comment here? https://github.com/Day8/re-frame/issues/137 — I have some ideas I'm already exploring and would like to know if there are any new updates/thoughts or maybe even progress on it

martinklepsch06:12:47

Thanks so much. And sorry for the nudge 🙂

martinklepsch09:12:54

Getting this when trying to run the karma tests: Error: No provider for "framework:cljs-test"! (Resolving: framework:cljs-test). Followed instructions in Contributing.md — any suggestions? 🙂

martinklepsch11:12:26

Issues was npm install -g karma vs npm install -g karma-cli 🙂

oliy13:12:28

Hi all, I just raised #296 in re-frame, it should be a super simple fix for something pretty badly broken!

martinklepsch13:12:47

@oliy It seems like you have a clear picture how to fix it. Consider opening a PR?

oliy13:12:36

I would happily but I don't know when I'll have time (I can't until I get home - github blocked here at work)

oliy13:12:59

But if no one has picked it up before I get a chance I will send a PR

oliy13:12:56

Very frustrating when I need to contribute from work... Painfully doing stuff on my phone!

martinklepsch13:12:07

@oliy Interesting workplace where you can't access github haha

oliy13:12:56

Well, we have read-only access. No writes allowed (not even allowed to sign in, so no chance of raising bugs even)

cmal14:12:11

Great. Only get no post?

oliy19:12:53

@cmal yeah I think that's how they implemented it

mikethompson19:12:54

Thanks to both @oliy and @martinklepsch - we'll review this morning and push a v0.9.1 (yes, it is morning here :-))

danielcompton19:12:40

@oliy hope it's not Juxt that's blocking your internet access? 😛

oliy19:12:38

@danielcompton heh, juxt runs on a steady supply of github and cat memes. Take either away and the whole train grinds to a halt

oliy19:12:17

Thanks @mikethompson I can supply a PR with some unit tests as well at some point

mikethompson19:12:36

@upgradingdave we've now using react-flip-move. Great find. Thanks! For others following along, please see this blog post: http://www.upgradingdave.com/blog/posts/2016-12-17-permutation.html

upgradingdave19:12:23

@mikethompson nice! Yeah, love the animation effects 😉

upgradingdave19:12:35

it makes boring ui stuff seem fun to use

mikethompson19:12:46

@upgradingdave So easy to use as well. I should be paying more attention to the React goodies that are out there.

danielcompton19:12:01

@oliy I'm fixing this now, just adding some tests first

danielcompton19:12:04

@oliy would be interested in hearing what you're using dyn-subs for. It might not be immediately obvious, but now that you can subscribe from the inside of a Reagent component we think that that takes care of most (all?) of the use cases of dyn-subs

oliy19:12:58

Essentially I have some time series data. The slice you look at depends on a date in the URL (which is my reactive arg) which I pass into my sub that knows how the data is stored

oliy19:12:50

If the URL changes I want to show the data for the new date

oliy19:12:26

I don't think there's a better way than the dyn sub at the moment (the sub is used from many places)

oliy19:12:45

I could get the date reaction outside the render loop and pass it as a value to a sub inside the render loop that I deref immediately - but that's relying on the render loop mechanics, and means I can't unit test this stuff

danielcompton19:12:55

Yeah, that's a good use case

danielcompton19:12:48

You could just subscribe to the same subscription in many different places

danielcompton19:12:57

with the date value deref'd

danielcompton19:12:11

subscription deduplication will avoid extra work

oliy19:12:55

I personally prefer using dyn subs, or building my own reactions with reg-sub-raw, so that I can unit test everything without having to get reagent involved

danielcompton19:12:12

as long as the deref is in the inner function, whenever it changes, the component will re-render which will change everything

oliy19:12:20

Then my view code takes data and emits hiccup rather than getting involved in control logic

oliy19:12:41

I don't want my view code to understand how to wire up subs and arguments, I just want it to render the atom I give it

owen19:12:04

can I ask how allowing subs within components removes all (most?) of the needs of dynamic subs? Is it because prior the sub would be closed over with its arguments and never "re-rendered" if done in the let of a (defn .. (let ... (fn form?

danielcompton19:12:53

but if you now subscribe from the inner function of a form-2 component (or just create a form-1 component), and deref any dynamic values then whenever the dynamic values change, that will trigger a re-render which will then cause a new subscription to be created

owen20:12:59

is creating that new sub performant? never sure what the impact of subs are, or how many people have found to be best

shaun-mahood20:12:24

@owen: I’m sure Daniel will correct me if I’m wrong, but subscribing onto an existing sub should perform better than directly onto app-db (given that all else is equal).

owen20:12:57

thanks! I guess my question is, if your subscribed to something like [:user [4]] and you click next or something and the component gets re-rendered and now subscribes to [:user [5]] will the sub to 4 get removed?

owen20:12:18

or does it get re-used with the new id?

owen20:12:32

ah, so you're saying, there would be a (sub [:users]) and then a specific (sub [:users [*id*]]) under that?

danielcompton20:12:20

They're kinda 2 separate issues

danielcompton20:12:29

What Shaun's talking about is that you should have extractor subscriptions and transforming subscriptions, to reduce the work that the transforming subscriptions have to do (https://github.com/Day8/re-frame/blob/master/docs/SubscriptionInfographic.md)

danielcompton20:12:59

Your question Owen, if I'm understanding correctly is asking about the performance impact of recreating a new subscription every time one of your dynamic values changes?

owen20:12:56

is that basically the same as the old dyn-sub method in the end?

danielcompton20:12:03

So you're right that there is more code running than if you were to create a dynamic subscription

danielcompton20:12:20

In absolute terms though I think it's such a tiny amount that it's unlikely to be noticeable

danielcompton20:12:01

Typically the expensive part of a subscription is your user code, which will be the same whether you were to do a dynsub or a standard subscribe inside a Reagent component

owen20:12:16

sure! A+ Thank you much!

danielcompton20:12:25

I think that's what you were meaning Shaun?

shaun-mahood20:12:55

@owen: Unrelated to your performance question, there are 2 ways to do that without dynamic subs that have worked well for me (I think it depends on the scale) - Sub to users in a parent component, then just pass the user info directly to your reagent component that does the rendering. With a small number of users, or if you want to reuse that component, this works really well as now it’s just a reagent component that you can use with devcards or in other places. - Create an active-user key in your app-db and subscribe to that directly, then just update the app-db. If it makes sense in your app, I really like this pattern as you can always tell the state of your app and can add extra info specific to the needs of the active editor/viewer. Great for CRUD style apps,

owen20:12:16

yeah the second is what I've been drawn to

owen20:12:40

I think from reading about om.next Ive started normalizing all the data in my front-end db

owen20:12:56

I would have still done this with dynsubs though

owen20:12:18

I just realized from the previous convo that 0.9.0 allows this without dynsubs

owen20:12:20

very interesting

shaun-mahood20:12:56

@owen: I find that most of the time when I use the active-user pattern on a new problem it exposes some part of my understanding that is lacking, and it’s a good place to do your normalization/de-normalization or whatever other transformation is necessary. Makes the subscription a lot simpler too, but I’m sure there are places where it doesn’t work that well.