Fork me on GitHub
#re-frame
<
2015-12-04
>
dfcarpenter00:12:58

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).

dfcarpenter01:12:58

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 😕

gadfly36101:12:54

@mikethompson what would be a good alternative to multimethods - hash-map?

gadfly36101:12:03

Happy to update template if multimethods arent a good option :)

mikethompson02:12:11

Using a map has its own issues when combined with figwheel.

mikethompson02:12:01

If you do:

(def panels  {
   :home   [home]
   :about   [about] }))

mikethompson02:12:37

The problem is that you have "caputured" a reference to home

mikethompson02:12:31

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.

mikethompson02:12:45

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

mikethompson02:12:09

(defn panel 
   [panel-id] 
   (case panel-id
      :home   [home]
      :about  [about]))

mikethompson02:12:33

But anyway, the template certainly works as written

gadfly36103:12:00

Ahh yeah, i remember experiencing exactly what you just noted in relation to maps and figwheel - it is certainly baffling when it happens!

gadfly36103:12:57

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

pupeno10:12:11

@mikethompson, @danielcompton: will you be around on Sunday between 12 to 18hs UTC to talk about https://github.com/Day8/re-frame/pull/118 ?

surreal.analysis15:12:05

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)))

surreal.analysis15:12:39

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

surreal.analysis15:12:53

I'm not sure why, but when I dispatch this event, the secretary route is run twice, no more

roberto16:12:49

accountant

nbdam16:12:43

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...

nbdam16:12:58

+1 for accountant, although it is not too hard to wire up secretary directly with browser navigation events...

nbdam16:12:48

look at readme for secretary under "Example with goog.History"

nbdam16:12:48

and today you should probably use Html5History

nbdam16:12:04

I think accountant does all that for you... but never used it..

gabe17:12:41

@nbdam: the only gripe i have w/ accountant is what happens when i refresh my browser

nbdam17:12:59

@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?

surreal.analysis17:12:45

I suppose I'm having a hard time understanding the right flow, then

surreal.analysis17:12:57

I thought it would be ideal to have any state change whatsoever be done with a handler

surreal.analysis17:12:07

And I saw the URL as a state change

surreal.analysis17:12:50

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?

nbdam17:12:23

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...

nbdam17:12:50

of course you should be able to jump directly to them when loading from the outside.. (refresh)

henryw37417:12:10

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.

nbdam17:12:29

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.

nbdam17:12:45

this can be done via Closure history api

nbdam17:12:04

2. this select approprivate view and renders it in reagent

nbdam17:12:13

3. the view fetches the necessary data

nbdam17:12:51

- 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

gabe17:12:18

@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

pupeno17:12:54

surreal.analysis: I use silk and pushy.

pupeno17:12:27

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/

dfcarpenter19:12:07

Great resource thanks!

danielcompton19:12:56

@pupeno: if you're around I can do a quick Hangout?

nbdam20:12:25

@gabe: yes, you have to to that.. some people serve app (index.html) with * route, but I don't like that to much...

surreal.analysis20:12:22

Yes, thanks to everyone who commented on the routing. Things are looking much clearer now

eigenjoy21:12:27

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

eigenjoy21:12:14

I was wondering if anyone has thoughts either way on that. Common practice would be to use reagent/atom for your global state, right?

eigenjoy21:12:13

Or maybe I’m missing that re-frame wraps that map in a reagent/atom somewhere under the hood

eigenjoy21:12:34

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.

eigenjoy22:12:10

right - makes sense. thanks @mikethompson

eigenjoy22:12:28

I think I was thrown off by the reagent/atom used for app-db in the readme

eigenjoy22:12:43

but that’s handled by re-frame internally

mikethompson22:12:20

Yep, you got it.

mikethompson22:12:16

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

mikethompson22:12:50

But I also know there's a time at which you just get sick of reading and want to "make" simple_smile