Fork me on GitHub
#re-frame
<
2020-07-13
>
genekim15:07:33

Drats — accidentally deleted my message. Reposting. Ever want to write a simple application, but writing a CLJS front end and a CLJ backend just seem like overkill? And the idea of having to learn Java Swing or JavaFX seems too daunting, but so too does the idea of writing a curses/terminal app (which doesn't even have an event loop)? @smith.adriane wrote something so cool, the membrane library — it lets you write a curses/terminal app that runs in your terminal or in a Swing application, but on top of re-frame. He helped me write a simple app yesterday that captures and displays keystrokes (hacked into the membrane sample app, which is the canonical TODO MVC app.) I'm so excited by this, because there's a whole class of simple applications that this seems perfect for! Thank you, @smith.adriane and @mikethompson !

genekim15:07:50

Here was his announcement of the project yesterday — so fun!!! https://clojurians.slack.com/archives/C073DKH9P/p1594229800342600

genekim15:07:15

Further discussions in #membrane!

phronmophobic16:07:54

Thanks for the kind words @U6VPZS1EK and also thanks to @mikethompson for re-frame. If this is something people are interested in, I could use some help designing re-frame compatible versions of basic reusable components like textboxes

Rob Knight16:07:42

I'm struggling with a design question. In my app I have a concept of "actions" that the user can take, which are determined dynamically based on things like selections made in the UI and data fetched from remote services. I have a network of subscriptions which aggregates this nicely into a single list of actions, and a UI which can show the user a searchable list of these actions. Subscriptions mean that the list updates dynamically, as it should. I also want to provide keyboard shortcuts for actions, and I've been looking at re-pressed as a library for this. Problem is that re-pressed requires me to "declare" the active keyboard shortcuts via an event (`set-keydown-rules`). So instead of having a data-driven reactive workflow as I do with the action list UI, I have to trigger events when the relevant data changes, if the change means that a new keyboard shortcut is now valid (or an old one is not). My ideal solution is simply to be able to trigger an event when a subscription changes. It seems like the easiest way to do this is to have a Reagent form-3 component which subscribes to the relevant subscription, and triggers an event in the :component-did-update handler, while returning nil from the render function. Is there a better design pattern for this?

ggiraldez17:07:02

removes the need of a react component and is more explicit in intent

Rob Knight17:07:15

Oh, that makes sense. Thanks! I was starting from the JS React-ish concept of renderless components, which felt like an un-Reagent/Re-frameish way of doing things.

gadfly36117:07:45

Regarding re-pressed, yeah, the recommended approach is to dispatch the set-keydown-rules event anytime the rules change. There is no limit to how frequent you can dispatch that even, so I think you can achieve the dynamic effect you want.

Rob Knight17:07:36

Yes, absolutely! My problem was just that I wanted to re-use the work I had already done in generating the action list, which is bundled up in a subscription, so I needed to figure out the right way of triggering an event on a subscription change.

👍 3
Rob Knight18:07:36

Does track! work with re-frame subscriptions? I'm trying it but not seeing the results I would expect.

ggiraldez19:07:04

re-frame subscriptions are reagent reactions, so yes, it should work

ggiraldez19:07:43

just make sure to deref the subscription inside the function

Rob Knight19:07:07

Yeah, that's what I'm doing.

Rob Knight19:07:36

(defn active-tracker []
  (let [active (re-frame/subscribe [::active])]
    (prn @active)))

(defonce tracker (r/track! active-tracker))

Rob Knight19:07:25

It prints once, but doesn't do anything when the subscription updates.

ggiraldez19:07:27

hmmm... my guess is it doesn't work because you are creating the reaction inside the tracking function

Rob Knight19:07:27

Oh, hmm. Where else am I supposed to create it?

ggiraldez19:07:40

(let [active (re-frame/subscribe [::active])
     tracker (fn [] (println @active))]
  (r/track! tracker))

ggiraldez19:07:47

that should work

Rob Knight19:07:58

Thanks, I'll try that

ggiraldez19:07:22

you will need to keep a reference of the result of track! for later disposal though... the example I gave you will leak the reference

Rob Knight19:07:54

This seems to behave the same way as the original version 😞

ggiraldez19:07:52

maybe something like:

(defonce tracker (let [active (re-frame/subscribe [::active])] (r/track! (fn [] (println @active))))

ggiraldez19:07:25

although probably an atom would be more appropriate to hold the reference

Rob Knight19:07:17

I'm doing that, but the basic functionality just doesn't seem to work. I must be missing something obvious but I can't work out what.

Rob Knight20:07:48

Ah, during re-frame setup/auto-reload I have a call to re-frame/clear-subscription-cache! and this breaks the subscription. As it's not part of a view/component, it doesn't get recreated. That was the problem.

👍 3
adam23:07:30

Any good open source re-frame project to get idea about to to properly structure the components, etc?

phronmophobic23:07:35

for specifically flexible and re-usable components