This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-12-04
Channels
- # admin-announcements (6)
- # alda (1)
- # announcements (3)
- # aws (4)
- # beginners (233)
- # boot (82)
- # cider (11)
- # cljsjs (21)
- # cljsrn (7)
- # clojure (262)
- # clojure-japan (1)
- # clojure-russia (129)
- # clojure-sg (2)
- # clojure-taiwan (2)
- # clojurecup (23)
- # clojurescript (162)
- # clojurex (3)
- # core-async (18)
- # cursive (81)
- # datavis (183)
- # datomic (23)
- # emacs (2)
- # funcool (25)
- # ldnclj (82)
- # lein-figwheel (3)
- # om (196)
- # onyx (74)
- # parinfer (7)
- # portland-or (12)
- # re-frame (60)
- # reagent (48)
- # slack-help (1)
- # yada (9)
Im going to rework it but yes, thats what I was/am doing. I have a list panel at /items and I want to get to /items/:id. Using the reframe template I modified the panels defmulti and the main panel function in the views.cljs to pass along an id (or whatever) when a particular panels method is called).
Aside: be slightly cautious about using multi-methods: http://stackoverflow.com/questions/33299746/why-are-multi-methods-not-working-as-functions-for-reagent-re-frame
That was helpful, thank you. I'm coming from react/react-router where I have several top level components (e.g. /apis, /docs, /iot each with some children) and the router passes along context to the top level components which the children components of each top level view can access. I am trying to apply a similar pattern here but also learning cljs/reagent/reframe at the same time 😕
@mikethompson what would be a good alternative to multimethods - hash-map?
@gadfly361: The way that template uses multimethods works fine. https://github.com/Day8/re-frame-template/blob/0a2e92a50d0b036ccb2a109c55756f5c2d78d7f6/src/leiningen/new/re_frame/src/cljs/views_recom_routes.cljs#L56
Using a map has its own issues when combined with figwheel.
If you do:
(def panels {
:home [home]
:about [about] }))
The problem is that you have "caputured" a reference to home
At the time the map is created.
If, later, you load a new version of home
via a figwheel reload, the map is not updated. It still has a reference to the old version.
That can be a bit baffling. Why isn't my new version getting used? After all, I saw figwheel load the new code. And I can see the new version in devtools!! But it isn't getting used. The old version is getting used. But if I refresh the page I get the new version. It must be something to do with caching. Arrgggghhhhh.
In some way, the most bulletproof way might be to use a function which contains a case
(defn panel
[panel-id]
(case panel-id
:home [home]
:about [about]))
But anyway, the template certainly works as written
Ahh yeah, i remember experiencing exactly what you just noted in relation to maps and figwheel - it is certainly baffling when it happens!
yeah, case
may be a good option to consider, i feel like there is less strain to understand what is happening than with multimethods which is a big plus. Only downside is it would be 'closed' where as adding multimethods is 'open' (thinking SOLID) ... but honestly, i dont think that is too much of a concern...so maybe case is the way to go
@mikethompson, @danielcompton: will you be around on Sunday between 12 to 18hs UTC to talk about https://github.com/Day8/re-frame/pull/118 ?
When building a website, how do people manage updating the URLs? My first implementation went something along the lines of:
(secretary/defroute project-profile "/project/:project-id" [project-id]
(dispatch [:select-active-project project-id]))
And the corresponding handler:
(register-handler
:select-active-project
standard-middlewares
(fn
[db [project-id]]
(set! js/window.location.hash (str "/project/" project-id))
(dispatch [:get-activities project-id])
(assoc db :active-project-id project-id)))
But the issue is that when the hash is changed after selecting an active project, that reruns the secretary route, which reruns the handler, which appears to rerun the secretary route
I'm not sure why, but when I dispatch this event, the secretary route is run twice, no more
It looks to me like you don't want to set the hash inside handler. Handler should be ran as a reaction (pun not intended, not a reagent reaction) to location change...
+1 for accountant, although it is not too hard to wire up secretary directly with browser navigation events...
@gabe: I don't use accountant.. i just browsed the sources a bit few months ago... what is the problem with refresh you are referring to?
I suppose I'm having a hard time understanding the right flow, then
I thought it would be ideal to have any state change whatsoever be done with a handler
And I saw the URL as a state change
But instead, on the "Select Profile" button or something similar, I should just change the url resulting in the secretary route dispatching the right event?
You can probably look at this differently.. but I find it useful to look at url changes as a kind of markers into the application state (stream) that you can go back and forward to with the browser controls...
of course you should be able to jump directly to them when loading from the outside.. (refresh)
I am using pushy lib (with bidi, although it says secretary is an option), and would set the url via its set-token!
fn. doing that wont trigger the pushy evt listener. https://github.com/kibu-australia/pushy. so, perhaps you can set the url via secretary? not sure. or use pushy.
I use the following process, and find it fairly robust and consistent with expected browser usage: 1. 'page' changes are done via urls - either user clicks a link or via location change2.
- data can be fetched from loca cache or from server of from wherever appropriate - tis is also described in re-frame docs -> you need to use multiple messages
@nbdam it's not a big deal, but with hash-based routing a refresh will hit my root url. With accountant I have to return index.html for everything
surreal.analysis: I use silk and pushy.
@surreal.analysis: I explain how here: https://carouselapps.com/2015/08/18/no-hashes-bidirectional-routing-in-re-frame-with-silk-and-pushy/
And if you want to see how it all fits together, you might be interested in my source code tour: https://carouselapps.com/2015/12/02/tour-of-the-source-code-of-ninja-tools/
Great resource thanks!
@pupeno: if you're around I can do a quick Hangout?
@gabe: yes, you have to to that.. some people serve app (index.html) with * route, but I don't like that to much...
Yes, thanks to everyone who commented on the routing. Things are looking much clearer now
Hey folks, question for you: In the re-frame-template
it set’s up the default-db
as a map, but the docs talk about using reagent/atom
for the app-db
I was wondering if anyone has thoughts either way on that. Common practice would be to use reagent/atom
for your global state, right?
Or maybe I’m missing that re-frame wraps that map in a reagent/atom
somewhere under the hood
ah I see, I think I’ve answered my own question: re-frame
manages the app-db
. Our default-db
is just a map of the initial state.
@eigenjoy: see the chain from here .... https://github.com/Day8/re-frame-template/blob/master/src/leiningen/new/re_frame/src/cljs/core.cljs#L19
will cause this event handler to be called: https://github.com/Day8/re-frame-template/blob/master/src/leiningen/new/re_frame/src/cljs/handlers.cljs#L5-L8
right - makes sense. thanks @mikethompson
Yep, you got it.
My advice to anyone getting up the re-frame learning curve is: - use the template - look carefully at the two examples: https://github.com/Day8/re-frame/tree/master/examples - read the Wiki. https://github.com/Day8/re-frame/wiki
But I also know there's a time at which you just get sick of reading and want to "make"