This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-03-13
Channels
- # arachne (2)
- # architecture (23)
- # bangalore-clj (5)
- # beginners (35)
- # boot (79)
- # cider (6)
- # cljs-dev (34)
- # cljsrn (9)
- # clojure (164)
- # clojure-argentina (2)
- # clojure-austin (4)
- # clojure-italy (7)
- # clojure-russia (40)
- # clojure-serbia (1)
- # clojure-spec (76)
- # clojure-uk (36)
- # clojurescript (47)
- # cursive (14)
- # datascript (2)
- # datomic (8)
- # dirac (19)
- # emacs (29)
- # heroku (7)
- # hoplon (35)
- # jobs-rus (1)
- # juxt (2)
- # leiningen (1)
- # lumo (23)
- # mount (4)
- # off-topic (22)
- # om (16)
- # onyx (19)
- # parinfer (10)
- # pedestal (47)
- # proton (5)
- # re-frame (88)
- # rum (1)
- # spacemacs (33)
- # sql (29)
- # uncomplicate (1)
- # unrepl (131)
- # untangled (5)
- # yada (12)
but ...?
It is used plenty in production, in lots of places https://github.com/Day8/re-frame#it-is-mature-and-proven-in-the-large These days you even see it explicitly mentioned in job ads: https://functionaljobs.com/jobs/8986-front-end-engineer-clojurescript-reagent-re-frame-at-apstra-inc
We've talked before btw about things like this- I think I pointed out redux-saga to you a while back.
I recall you saying you didn't love the approach, I'd like to take a closer look at what you came up with as an alternative.
It' more like... well there's a lot of nice stuff around redux (like 'styled-components,' for instance, which is basically the best thing ever) and I'm curious about the experience of doing production work in re-frame.
I'm curious because I'm considering using it for a new project, so... essentially because I really like your approach.
We’ve got a ~20k line and rapidly growing re-frame + Material-UI app in production @tagore Have previously used Redux. I can say as a personal observation that re-frame is hands down the best thing I’ve ever experienced for building front-end apps. I certainly wouldn’t consider going back to Redux.
@superstructor OK, well that is good to hear.
I mean- on some level I feel like you should make your own judgments, but... it's nice, before leaping into the void, to hear that others have done so withut falling to their deaths 😉
I will say that the codebases I'm working on at the moment are a lot bigger than that, but...
@tagore regarding redux-saga alternatives ... here is an example which is specific to startup (there is breif discussion about comparisons to redux-saga at teh bottom) https://github.com/Day8/re-frame-async-flow-fx/blob/develop/README.md
I don't now if you remember but I think I pointed out redux-saga to you last spring, actually.
i know what you mean about ecosystem .... the bigger the better
i love the idea of leveraging what other smart people have done
We had a kind of long conversation about side-effects/representing them as dara, IIRC.
Right, yes, I went looking at it. i realised it was fundamentally a way of coding state machines
At least that was my interpretation
So when you take that view, and you realise that events should be the FSM triggers
ANd you end up in a different place to redux-sagas
Well, at least I did :-)
Most things that can be represented as "flows" really are just that. and it's nice to have a formal model rather than lots of ad-hoc implementations.
Yeah, it puts state outside of the main state container
(the state of the FSM)
Half of it is essentially not-very-formal state machines, and the other half is kind of like core.async.
It captures state within the ES6 generator functions themsleves
Anyway, gotta run ... the philosophy is here: https://github.com/Day8/re-frame-async-flow-fx/blob/develop/README.md#design-philosophy
I've done a lot of redux (am doing a lot, really,) I've done talks n the subject, and...
Yes it is
We do get to use a fair bit of react
For example we use https://github.com/joshwcomeau/react-flip-move
That's the nice thing about using reagent
Interoperates reasonably well
Anyway, i really do have to go now
I'm inclined to think that for my new thing I'd rather be doing clojurescript and re-frame.
Btw, I've been reading the docs, and I'm impressed- I've been following re-frame for a long time, and I like where you're going with it.
@tagore yes, versions 8 and 9 (last year) were a substantial step forward, both for the programming model and the docs
We try hard to keep detailed change logs https://github.com/Day8/re-frame/blob/master/CHANGES.md
with the re-frame i can write RN applications without errors and without a need to debug code at all, but only two kind of problems happen sometimes, and they bring pain
1) parinfer breaks reagent view, it compiles fine but crashes in runtime, so here would be great to have devcards analogue , i'm thinking about it
2) runtime error in the event handler, very rare case, but here re-frisk сould help, it would be helpful if i could see event data which cause the error, but now re-frame provides only add-post-event-callback
, here would be greate to have add-pre-event-callback
@mikethompson maybe you can advise something on the second point, thanks
Is this what you are after? https://github.com/Day8/re-frame/issues/236
Something more than the debug
interceptor?
i have an effect similar to https://github.com/Day8/re-frame-http-fx that takes from a channel (http request) and dispatches the results to be saved in my state. i want to close any previous channels from the request so that i'm only returning the results from the most recent request. my current method is to store the channel in app-db whenever the parent handler event is called, but first close any channels in that location before dispatching the effect. i find myself doing this a lot... is there a better way than my following example? can i move the channel closing somewhere outside of the starting event?
(reg-event-fx
:qb/fetch-preview
(fn [{db :db} [_ service query]]
(let [new-request (fetch/table-rows service query {:size 5})]
{:db (-> db
(assoc-in [:qb :fetching-preview?] true)
(update-in [:qb :preview-chan] (fnil close! (chan)))
(assoc-in [:qb :preview-chan] new-request))
:im-chan {:on-success [:qb/save-preview]
:chan new-request}})))
the simple effect being..
(reg-fx
:im-chan
(fn [{:keys [on-success chan]}]
(go (dispatch (conj on-success (<! chan))))))
@joshkh you could construct the channels in a let, then issue several of your queries, in the callbacks close over the channels so you can reference them when they come back. Not sure if I'm understanding correctly, but you shouldn't be closing the other channels when you get a message in one of them. Using alts! or alt! is safer
thanks @danielcompton . the simple scenario would be: i have a button that, when clicked, fires an event that makes an HTTP request and stores the results to be displayed. if i click the button over and over and then stop i'm not guaranteed that final result is from the last event fired due to the async behavior of the ajax call.
right. maybe you should cancel a query when the next one is issued?
or order their results?
i think that's what i'm doing now - canceling the query by closing previously opened channel and then replacing it with the new request channel.
i might be doing exactly what i'm supposed to! it's just that i'm storing short lived channels in my app state and i'd imagine that's no bueno for serialization.
Not strictly a re-frame issue, but... Does anyone have experience using Chart.js with reagent? In particular, I started with the example form-3 component here: https://gist.github.com/edwthomas/b1f653405e2827357133f7e3c245bea0
Then I wanted to handle the case of :component-did-update
and am not sure how to do it. This code, for example, almost works, but has a problem:
(defn chartjs-component
[{:keys [canvas-id type data options]}]
(reagent/create-class
{:display-name "chartjs-component"
:component-did-mount
(fn [this]
(js/Chart. (.getContext (.getElementById js/document canvas-id) "2d")
(clj->js {:type type
:data data
:options (merge chartjs-global-config options)})))
;; Initially unclear how to have charts update automatically, but
;; looked at the reagent/core docs and found reagent/props has the
;; new/changed args:
:component-did-update
(fn [this]
(js/console.log "component-did-update this" (pr-str (js-keys this)))
(let [{:keys [data options]} (reagent/props this)]
#_(reagent/force-update this) ; does not work
(js/Chart. (.getContext (.getElementById js/document canvas-id) "2d")
(clj->js {:type type
:data data
:options (merge chartjs-global-config options)}))))
:reagent-render (fn [] [:canvas {:id canvas-id :width "640" :height "480"}])}))
The problem with the :component-did-update
function above, is that another chart.js chart object is created, and weird behavior then results from having two chart objects. Instead, I'd like to either destroy the old chart and draw a new one, or, use the Chart.js update
method to take the new data. Either way, I need some kind of reference to the old/original chart object; and I don't see/understand how to get that from the this
passed in to the function under component-did-update
Any help appreciated!@limist http://nils-blum-oeste.net/clojurescripts-reagent-using-props-in-lifecycle-hooks/
in your case you’re passing properties correctly so you have to find out how to use update
in chartjs context
if I remember correctly they have update
method which should be called when the original dataset has changed
@kishanov Yes, that's the problem: is the actual chart.js object/instance somewhere in the this
object? If so, where? Once I have it, I can invoke the chart.js update
method
What I don't quite get (and didn't see docs for) is what exactly the this
object is, as received by the form-3 functions...
@limist I don’t think it wil be anywhere in this
object, cause it was created by chartjs after you rendered it. I think in component-did-update
you can find chartjs object via jquery selector and do imperative update there
Does this help ? https://github.com/Day8/re-frame/blob/master/docs/Using-Stateful-JS-Components.md (I haven't actually tried to understand the specifics of your problem, just throwing this link over the wall) ?
@limist ^^^ Notice the various links down the bottom of that page too.
@mikethompson Yes, that does/will help, thanks! Good to know the right terminology of the problem for starters; will take a closer look and start some refactoring.