re-frame

https://github.com/Day8/re-frame/blob/master/docs/README.md https://github.com/Day8/re-frame/blob/master/docs/External-Resources.md
superstructor 2021-04-20T00:01:32.209600Z

Thanks @andre I have updated re-frame-template to use the latest re-frisk release.

1❤️
lilactown 2021-04-20T00:10:44.209900Z

reg-* should really be macros that def vars don't @ me 😉

2👍1
prnc 2021-04-20T12:42:49.211100Z

is this > (def event:event-name ::event-name) some kind of namespacing by convention, i.e. the use of : in the symbol there? @emccue

paulbutcher 2021-04-20T14:17:19.212700Z

I feel that this is probably a FAQ, but I haven’t been able to scare up an answer. Is there some way to “weakly subscribe” to something in the database? I.e. I want access to the value within my component, but I don’t want my component to update when the value changes. Is this possible?

paulbutcher 2021-04-21T08:11:15.235400Z

Thanks!

p-himik 2021-04-20T14:18:40.212800Z

Using a form-2 Reagent component should help.

p-himik 2021-04-20T14:19:23.213Z

Or reagent.core/with-let with @ being inside its bindings form.

paulbutcher 2021-04-20T14:22:48.213200Z

I think I see what you’re suggesting. If I understand, that will allow me to access the value as it was when the component was created. I’m interested in whatever the value happens to be right now. Let me try to explain: I have :x, :y, and :z in the app-db. I want my component to update whenever :x or :y change, but when it updates, take whatever the current value of :z is into account. If I subscribe to :z, it will also update whenever :z changes. Perhaps I can do that with a form-2 component, but I’m not sure I can immediately see how?

p-himik 2021-04-20T14:25:53.213400Z

I see. Well, a proper re-frame friendly approach would be to have an extra key, something like :z-for-x-y, that would be set to the value of :z only when :x or :y is changed. And you would just subscribe to the value of :z-for-x-y - no magic whatsoever. If you don't have a small known set of events that update :x and :y where you could put the code updating :z-for-x-y, you can use a global interceptor for it.

paulbutcher 2021-04-20T14:34:41.213600Z

Ah, got you. Thanks. Perhaps I should explain what I’m trying to do in more detail - there may be a completely different way to solve the problem: I’m writing a component which wraps a large pre-existing Javascript component (https://vega.github.io/vega/). I’m doing this by having a component like this:

(defn vega-view []
  (let [data @(re-frame/subscribe [:vega-data])]
    [:div {:ref #(create-view % data)}]))
The create-view function creates the Vega view, and everything’s good. Except… Vega is full of its own state that I need to occasionally interact with. In particular if my component repaints (because data has changed) I want to read the values out of the Vega component, create a new Vega component, then put the values back. Currently I do this by having a clojure.core/atom that I store the Vega view in, which I refer to within create-view. I’d like to put it in app-db however because other components elsewhere within the app also need access (and will need to refresh if it changes). Perhaps I’m pushing re-frame in a direction it doesn’t want to go here though.

p-himik 2021-04-20T14:38:52.213800Z

Just use https://github.com/vega/react-vega. ;) It deals with all that.

p-himik 2021-04-20T14:39:22.214100Z

And use it via regular Reagent/React interop - works like a charm for me.

emccue 2021-04-20T14:40:52.214300Z

yeah

paulbutcher 2021-04-20T14:44:26.214500Z

Ah! Good luck to find someone else doing something very similar! I did try to use react-vega back when I started down this road, and got into a real mess. Perhaps I should revisit. I’m not sure that it could solve the problem that I’m trying to solve though? I’m programmatically generating my Vega spec (because the spec changes depending on the specifics of the data being visualised) and want to save the values of certain signals from the previous instance of Vega and copy them into the new one.

p-himik 2021-04-20T14:47:31.214700Z

I also generate the spec depending on the data. But I've never tried preserving signal values.

emccue 2021-04-20T14:48:58.214900Z

might macro it up at some point if the pattern holds, but for now biting the bullet of typing so we don't get hard locked in

paulbutcher 2021-04-20T14:50:45.215100Z

No worries. I think you’ve answered my main question which is that my initial thought about how to use re-frame won’t fly (for which many thanks). I can certainly find a way to make it work, it’ll just be a bit messy (which is fine - the interface between a nice functional re-frame app and a very imperative Vega component will always get a bit messy at the join…)

paulbutcher 2021-04-20T14:51:09.215300Z

I’m curious now - what are you visualising?

emccue 2021-04-20T14:55:01.215500Z

so for @p-himik's example we would do this

;; Events
(def event:user-typed ::user-typed)

(defn user-typed [text]
  [event:user-typed text])

(defn handler:user-typed
  [{:keys [db]} [_ text]]
  {:db (update db ::model/page-state
                  :user-input assoc text)
   :fx []})

(rf/reg-event-fx event:user-typed handler:user-typed)
;; view
(defn input [{:keys [user-input]}]
  [:input {:value user-input
           :on-change #(rf/dispatch (events/user-typed %))}])

1👍
p-himik 2021-04-20T15:01:37.215700Z

I'm working together with the Utrecht University on a platform that would allow users to select the right breeding partners for their dogs, so all the breeding regulations are followed - to avoid any diseased offspring. The platform itself is not public yet, but here are a couple of charts from the work in progress: file:///home/p-himik/Pictures/screenshots/Screenshot_20210420_175902.png

p-himik 2021-04-20T15:02:17.216100Z

Where would you use user-typed without dispatch?

paulbutcher 2021-04-20T15:02:40.216300Z

Very nice! 👍

emccue 2021-04-20T16:28:11.216600Z

in the tests like bove

p-himik 2021-04-20T16:29:27.216800Z

Ah, I see now, thanks.

valtteri 2021-04-20T17:05:33.217Z

You can also check this out. I’ve been using this strategy to wrap OpenLayers, which is highly stateful and imperative. https://github.com/day8/re-frame/blob/master/docs/Using-Stateful-JS-Components.md

valtteri 2021-04-20T17:06:01.217300Z

Warning: it’s not fun but it works. 🙂

kennytilton 2021-04-20T23:02:25.221500Z

So I am pitching in on a re-frame project and cannot figure out what version of re-frame is being used. The shadow-cljs.edn pulls in only [day8.re-frame/re-frame-10x "0.6.0"]. I cannot find any other "re-frame" linkage. They also use NPM, but npm list shows only react stuff. Damn I miss project.clj. 🙂 Anyone have any idea how to find out what version they are using. Their timezone is unconscious right now or I would ask them. Thx! 🙏

kennytilton 2021-04-20T23:09:51.221600Z

Ah, found a re-frame-1.1.2 jar under shadow-cljs. Bingo.