This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-03-08
Channels
- # bangalore-clj (5)
- # beginners (6)
- # boot (66)
- # cider (48)
- # cljsrn (14)
- # clojure (699)
- # clojure-austin (2)
- # clojure-berlin (1)
- # clojure-boston (5)
- # clojure-dev (3)
- # clojure-india (7)
- # clojure-italy (24)
- # clojure-nl (5)
- # clojure-russia (33)
- # clojure-spec (30)
- # clojure-uk (64)
- # clojure-ukraine (22)
- # clojurescript (123)
- # clojurewest (1)
- # cursive (18)
- # datascript (44)
- # datomic (12)
- # dirac (46)
- # figwheel (1)
- # gsoc (5)
- # hoplon (6)
- # immutant (29)
- # instaparse (1)
- # juxt (26)
- # lein-figwheel (5)
- # leiningen (4)
- # luminus (8)
- # mount (56)
- # off-topic (60)
- # om (67)
- # om-next (1)
- # onyx (8)
- # proton (28)
- # re-frame (125)
- # ring (3)
- # ring-swagger (3)
- # specter (22)
- # testing (2)
- # unrepl (1)
- # untangled (91)
Where do you guys put business logic that needs to be ran when something happens? For example, when a value in my state was x
and is now y
, dispatch event a
. The change from x
to y
could come from any number of sources, but I always want to listen for the change from x
to y
and react upon it. I could setup a watch via add-watch
on a re-frame subscription, but that feels icky. I could also add a call to the function that determines if event a
needs to be dispatched on all possible sources that could trigger x
-> y
, but then I am repeating code. Is there another solution or does one of the aforementioned methods actually end up working out well in a large application?
I have just a small hobby project, but there I have a separate cljc file for pure functions which I use at multiple places, this also makes it possible to use the same functions to compile to java, if needed.
I’d like to use reagent-forms inside a re-frame app. I need to pass an atom to the form as explained here - https://github.com/reagent-project/reagent-forms#binding-the-form-to-a-document
I want this atom to be part of the re-frame app-db
How do I do that?
@viebel, not sure if storing an atom in an atom is a good idea
can't you use a cursor (a sub-view of an atom) or a reaction?
I could but I don’t know how to do that...
@viebel I do that kind of thing in my code, just use a re-frame subscribe instead of an atom
I’m not sure what I’m doing is “best practice,” but I find it helpful to divide my main app-db into two parts, :model and :ui. The :model part represents the “real” data, and the :ui part holds things like forms, fields, etc.
under :ui, I’ll also have things like :login-form, which holds the data for the :username and :password fields.
I probably should be using reactions to extract the :login form as a kind of cursor, but in practice I tend to just write re-frame subscribe functions that do (get-in [:ui :login-form :username]…
I’m still mentally upgrading my re-frame usage to adapt to the newer style, so I haven’t integrated all the latest best practices yet.
@pesterhazy can u guide me about how to use a cursor or a reaction?
I tried
(defn new-expense []
(let [doc (subscribe [:new-expense-data])]
(fn []
[:div
[:form.form-inline
[bind-fields (form-template doc) doc]
]])))
@viebel, let me see
not 100% familiar with re-frame but in the final analysis subscribe
is just a reaction right?
not unlike just calling @re-frame.db/app-db
and retrieving the right key
what does your app-db look like?
(re-frame/reg-sub
:new-expense-data
(fn [db]
(get-in db [:new-expense])))
so you could pass (r/cursor app-db [:new-expense])
r/cursor
creates an atom-like object that you get deref and swap just like the original atom
all operations are translated to deref+get-in or swap+assoc-in
n.b. I'm not familiar with reagent-forms so I may be making incorrect assumptions about how it works
let me try
so bad we don’t have yet re-frame in klipse
It would have been much easier to solve this issue
totally!
here's an example for r/cursor though: http://app.klipse.tech/?cljs_in.gist=pesterhazy%2F2540ab6458f6681656bfd8bf5a4af4cb&container=1
@pesterhazy I tried:
(re-frame/reg-sub
:new-expense-data
(fn [db]
(r/cursor db [:new-expense])))
It doesn’t work - I get an exception when the app loads
don't think that's going to work
personally I'd just go around subscriptions and use app-db directly. Any reason not to?
Let me try
iirc reagent-forms needs to update the atom - a reaction
or subscribe
isn't going to work
that's why I suggested a cursor (or r/track in combination with r/wrap if that's not sufficient)
yeah, that could work
i seem to remember experimenting with reagent-forms a while back and finding it didn't add much value for a re-frame app
I’m new to re-frame @mccraigmccraig
How would you handle forms in a re-frame app?
I think that goes for a lot of libraries that add functionality to reagent in my experience
@pesterhazy how do I retrieve the app-db from my re-frame app?
@viebel re-frame.db/app-db
is the atom
it's a global: re-frame.db/app-db
@pesterhazy It works!!! 👏
@viebel i don't use any forms lib - i have a bunch of input view components, which update a form-model in app-db on-change, and some ajax machinery ... when it's time i send the form-model to the api and dispatch
the response to update app-db
@mccraigmccraig that's pretty much what I do as well
quick question about dynamic subscriptions. can the :<-
macro be mixed with subscription arguments? i can't seem to get the destructuring right:
(reg-sub
:current-possible-values
:<- [:current-mine]
(fn [current-mine value]
"some-value"))
current-mine
does represent the value of the current-mine
subscription, but i can't get the value that i'm passing into (subscribe [:current-possible-values "user123"])
Info can be found at https://github.com/Day8/re-frame/blob/master/examples/todomvc/src/todomvc/subs.cljs
apparently slack has threads now? responded in the main chat. @kasuko @U054BUGT4
Yeah. I'm not a fan so far.... I meant to be in main chat too!
i would expect value
to be equal to user123
but instead it's the subscription vector keyword [current-possible-values]
. i'm sure it's just a destructing problem...
and, as usual, after seeking help i figured it out. not sure why it wasn't working before. (fn [current-mine [_ arg]])
Hey all. Does anyone use emacs as their repl? If so. I'm having issues with a branch new app (just built from the template). Rhino seems to take forever to start, but I can get to the repl buffer. If I try to compile a ns using C-c C-k
I get the following Caused by: clojure.lang.ExceptionInfo: No such namespace
and clojure.lang.ExceptionInfo: failed compiling file:/home/me/code/fudge/src/cljs/fudge/core.cljs {:file #object[java.io.File 0x52e7523e "/home/me/code/fudge/src/cljs/fudge/core.cljs"]}
This is using cider-jack-in-clojurescript-repl
. I'm new to cljs but know my way around clojure pretty well.
@madstap if that's the way things are done in this world I'd be happy to try. I'm just used to using rhino to play with data while coding?
Is the usual workflow to use lein figwheel dev
. How would you, for example check the state of your db atom?
My workflow is that I first eval
(setq cider-cljs-lein-repl
"(do (use 'figwheel-sidecar.repl-api) (start-figwheel!) (cljs-repl))")
in scratch buffer, then do cider-jack-in-clojurescript
in a cljs fileI read somewhere to put it emacs.d, but that interferes when I try to use boot stuff, so I just eval it in scratch every time ¯\(ツ)/¯
in one of them there should appear, after a little while, something like:
Figwheel: Starting server at
Figwheel: Watching build - dev
Compiling "resources/public/js/compiled/app.js" from ["src/cljs"]...
Successfully compiled "resources/public/js/compiled/app.js" in 6.215 seconds.
Figwheel: Starting CSS Watcher for paths ["resources/public/css"]
Launching ClojureScript REPL for build: dev
Figwheel Controls:
(stop-autobuild) ;; stops Figwheel autobuilder
(start-autobuild [id ...]) ;; starts autobuilder focused on optional ids
(switch-to-build id ...) ;; switches autobuilder to different build
(reset-autobuild) ;; stops, cleans, and starts autobuilder
(reload-config) ;; reloads build config and resets autobuild
(build-once [id ...]) ;; builds source one time
(clean-builds [id ..]) ;; deletes compiled cljs target files
(print-config [id ...]) ;; prints out build configurations
(fig-status) ;; displays current state of system
(figwheel.client/set-autoload false) ;; will turn autoloading off
(figwheel.client/set-repl-pprint false) ;; will turn pretty printing off
Switch REPL build focus:
:cljs/quit ;; allows you to switch REPL to another build
Docs: (doc function-name-here)
Exit: Control+C or :cljs/quit
Results: Stored in vars *1, *2, *3, *e holds last exception object
Prompt will show when Figwheel connects to your application
Then you can eval something like (js/alert "qwerty")
and it should pop up in the browser
The order is important, if you try to eval anything before opening the browser, it "misbehaves" and starts a rhino repl
So I have noticed something odd, whenever I try to evaluate my core ns (`C-c C-k`). I get an error similar to the following:
But I am able to evaluate expressions using C-x C-e
from within the same ns. Does anyone else see this?
if I wanted to make a wrapper for the http-fx effect handler to streamline interaction with my API service, should I do that by creating another effect handler, or just an event-fx?
@shader in my case i have a library that i wrote to interact with my API which returns channels. then i have a simple effect like this:
(reg-fx
:im-chan
(fn [{:keys [on-success chan]}]
(go (dispatch (conj on-success (<! chan))))))
and call it like this:
(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}})))
i store the channel in app-db so that i can close it the next time the event fires, otherwise the results from the first request might arrive after the second request
(i wish the effect could close the channel itself without having to pass it in, but i haven't found a way to do that)
joshkh: it looks like you're making the request with fetch/table-rows, and simply using im-chan to wait for the response?
@viebel after you get the cursor, you need to dereference it. This is how we do it, or we have crazy amounts of subscriptions that fire anytime anything in the app-db changes. Imagine then if you add a mouse coordinates listener and put that in app-db...
I have a big react/npm/webpack. there is some way to develop some components in clojurescript? Some tutorial to do it?
@kasuko i haven't combed the documentation recently so i don't know if it's covered in detail, but :<-
is a shortcut for pulling in other registered subscriptions. there's an example in the todomvc app here: https://github.com/Day8/re-frame/blob/master/examples/todomvc/src/todomvc/subs.cljs#L120
probably a really bad example, but i find it useful for combining filters on collections: https://github.com/intermine/redgenes/blob/dev/src/cljs/redgenes/sections/lists/subs.cljs#L53
reagent renders inside a RAF. That can lead to subscriptions handlers "running" inside RAF. But event handlers can happen at any time
@mikethompson : thanks!
@qqq when people ask how event handling is done I direct them to this: https://github.com/Day8/re-frame/blob/master/src/re_frame/router.cljc#L8-L61 It seems to answer all the questions.
qqq: I put a quil canvas inside a reagent component, but quil for JavaScript don't support svg I think.
@U26FJ5FDM: I'm using svg inside reagent right now