zengod
zengod

Reputation: 1174

How to serve the correct panel in reframe based on the uri?

I have several panels defined for my app like so:

(defmulti panels identity)
(defmethod panels :panel1 [] [panel1])
(defmethod panels :panel2 [] [panel2])
(defmethod panels :panel3 [] [panel3])

I can use bidi+pushy in the client side to push a route, say /panel1-uri when an event (click in this case) occurs and change the panel using dispatch. But when I access localhost:5000/panel1-uri directly through the browser, this doesn't work since the /panel1-uri route doesn't exist in the server.

So I create a route in my server /panel1-uri, that just serves index.html and add the key of the panel I want to show in the header of this route's response. Then I create an anchor href to localhost:5000/panel1-uri rather than dispatching an event (to push /panel1-uri), but of course, this still serves the default panel. However, the response I have received from clicking href does contain the correct panel key in its header. How can I access this header I received from the response after clicking href and use it to change the panel?

Alternatively, Is there a better way to approach the problem of serving uri's that not only work with events in the client-side but also when entered directly into the browser?

Upvotes: 0

Views: 558

Answers (1)

Geoffrey Gaillard
Geoffrey Gaillard

Reputation: 293

I solved this issue in a similar way as you did:

  • one route /pannel-1 => index.html on the server-side,
  • using pushy to leverage HTML5 history.

You don't need to pass data back to the client-side in the HTTP Response header. The trick is that Pushy will trigger when started, so you just need to wait for your page to load to call pushy/start!. In other words, mount your React app first, then start the router.

Here is a bit of my code:

(ns my.router
  (:require [pushy.core :as pushy]))

;; We need to call `pushy/start!` as the last action in the boot process or it
;; might produce unexpected behavior. Pushy uses goog.history, and the goog
;; history need to be loaded before the app starts and before the document has
;; finished loading, but triggering the routing mechanism need to be done once
;; the world is set up.
;; @see https://google.github.io/closure-library/api/goog.History.html
(defn start! []
  (pushy/start! history))

In your core namespace:

(ns your.app.core
  (:require [your.app.router :as router]))

(defn ^:export boot! []
  (do-stuff-to-set-up-your-app-state)
  (mount-your-react-app)
  (router/start!))

In your index.html:

<script … src="app.js"></script>
<script type="text/javascript">
  your.app.core.boot_BANG_();
</script>

Upvotes: 1

Related Questions