Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added an additional parameter to the dispatch! function to provide the matched route with optional context. #61

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ A client-side router for ClojureScript.
* [Route matchers](#route-matchers)
* [Parameter destructuring](#parameter-destructuring)
* [Query parmeters](#query-parameters)
* [Request context](#request-context)
* [Named routes](#named-routes)
- [Example with history](#example-with-googhistory)
- [Available protocols](#available-protocols)
Expand Down Expand Up @@ -171,6 +172,29 @@ regular expression matchers.
```


#### Request context

If `dispatch!` is called with an additional context value, that
value will be available in `:request-context` for string route
matchers and to the last element for regular expression matchers.

```clojure
(defroute "/users/:id" [id request-context]
(js/console.log (str "User: " id))
(js/console.log (pr-str request-context)))

(defroute #"/users/(\d+)" [id {:keys [request-context]}]
(js/console.log (str "User: " id))
(js/console.log (pr-str request-context)))

;; In both instances...
(secretary/dispatch! "/users/10" {:page :users})
;; ... will log
;; User: 10
;; "{:page :users}"
```


#### Named routes

While route matching and dispatch is by itself useful, it is often
Expand Down
24 changes: 14 additions & 10 deletions src/secretary/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -311,16 +311,20 @@
(str "/" uri)))

(defn dispatch!
"Dispatch an action for a given route if it matches the URI path."
[uri]
(let [[uri-path query-string] (string/split (uri-without-prefix uri) #"\?")
uri-path (uri-with-leading-slash uri-path)
query-params (when query-string
{:query-params (decode-query-params query-string)})
{:keys [action params]} (locate-route uri-path)
action (or action identity)
params (merge params query-params)]
(action params)))
"Dispatch an action for a given route if it matches the URI path.
Optionally provide context to the route."
([uri] (dispatch! uri nil))
([uri context]
(let [[uri-path query-string] (string/split (uri-without-prefix uri) #"\?")
uri-path (uri-with-leading-slash uri-path)
query-params (when query-string
{:query-params (decode-query-params query-string)})
request-context (when context
{:request-context context})
{:keys [action params]} (locate-route uri-path)
action (or action identity)
params (merge params (merge query-params request-context))]
(action params))))

(defn invalid-params [params validations]
(reduce (fn [m [key validation]]
Expand Down
28 changes: 28 additions & 0 deletions test/secretary/test/core.cljs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,34 @@
(is (= (secretary/dispatch! (user-route {:id "2"}))
{:id "2"}))))

(testing "dispatch! with query-params and context"
(secretary/reset-routes!)
(defroute #"/([a-z]+)/search" [letters {:keys [query-params request-context]}]
[letters query-params request-context])

(is (= (secretary/dispatch! "/abc/search" {:page :index})
["abc" nil {:page :index}]))

(is (= (secretary/dispatch! "/abc/search?flavor=pineapple&walnuts=true" {:page :index})
["abc" {:flavor "pineapple" :walnuts "true"} {:page :index}])))

(testing "dispatch! with regex routes and context"
(secretary/reset-routes!)
(defroute #"/([a-z]+)/(\d+)" [letters digits {:keys [request-context]}]
[letters digits request-context])

(is (= (secretary/dispatch! "/xyz/123" {:page :index})
["xyz" "123" {:page :index}])))

(testing "dispatch! with vector routes and context"
(secretary/reset-routes!)
(defroute ["/:num/socks" :num #"[0-9]+"]
{:keys [num request-context]}
[(str num "socks") request-context])

(is (= (secretary/dispatch! "/bacon/socks" {:page :index}) {:request-context {:page :index}}))
(is (= (secretary/dispatch! "/123/socks" {:page :index}) ["123socks" {:page :index}])))

(testing "named routes"
(secretary/reset-routes!)

Expand Down