clj-commons / secretary

A client-side router for ClojureScript.
773 stars 64 forks source link

Circular Dependencies -- Suggestions? #68

Closed caryfitzhugh closed 9 years ago

caryfitzhugh commented 9 years ago

Hi

I have an app which uses Secretary to define the routes for the system.

so routes.cljs has the route definitions.

routes.cljs references some controller namespaces in order to route people to the right controller when things change.

Additionally, controllers sometimes need to send people places.

routes -> controller -> routes

This is a circular dependency.
I believe there's no way around it since in my case the things which are accepting being routed-to also want to route people to other places.

In my earlier home-grown efforts I had split paths and routes into two files so that I could avoid this.

e.g.

routes -> paths  (to generate the link btwn URL paths and behaviors)
routes -> controllers (to shuttle control to a controller)
controllers -> paths (to generate paths to things)

Is there something like this in Secretary / has someone come up with any solutions other than "reorganize your code"?

I looked and there seemed to only be the "mother-macro" defroute, and I wasn't clear on how to split that apart.

This seems like such a common issue that I hope there is something simple...
like:

paths.cljs
(defpath article  "/article/:id")
;; Returns a (defn article-path which just generates a "string")
;; This can perform the machinations to generate URLs correctly

routes.cljs
(defroute (article-path :id)
   (do-whatever id))
;; So here, the article-path is handing back a stirng with the first parameter set to :id
;; e.g. /articles/:id 

Something along those lines. Thanks!

caryfitzhugh commented 9 years ago

I ended up doing what I proposed above. Create a paths.cljs namespace. All these puppies produce a string.

  (defn article-path [article-id & args]
    (as-path "articles" article-id args))

And pass those into the defroute macro.

  (defroute (p/article-path :aid) [aid]
    (articles/show-article app-state/current aid))

Only sticky part was that I had to write some functions to dispatch and prepend with the "#" in certain situations. Other than that...

Don't know if anyone else cares, but I'll leave it here in the comments so maybe it'll help someone googling for "secretary circular dependencies"