Getting POSTed data in a Clojure / Ring / HttpKit application

511 Views Asked by At

I'm writing a simple HttpKit / Ring application and am trying to post some data from a form to it.

Here's the relevant part of my server code :

(defn save-page [request]
  (let [qs (:query-string request)
        fp (:form-params request)]
    (println "SAVE PAGE :: ")
    (println (str request))
    (println (str "CCCC" fp))
    (println (str qs))))

(defn handler [{:keys [uri request-method] :as request}]
  (let []
    (cond 
      ; view a page 
      (= uri "/clj_ts/view")
      (get-page request)

      (= uri "/clj_ts/save")
      (save-page request)

      :otherwise 

      .. STUFF )))

(defn -main [& args]
  (-> #'handler
      (wrap-content-type)
      (wrap-keyword-params)
      (wrap-params)
      (wrap-reload)
      (wrap-resource "clj_ts")
      (run-server {:port 0})))

Here's the client-side code which posts to it.

(defn generate-form-data [params]
  (let [form-data (js/FormData.)]
    (doseq [[k v] params]
      (.append form-data (name k) v))
    form-data))

(defn save-page! []
  (let [page-name (-> @db :current-page)
        new-data (-> js/document
                     (.getElementById "edit-field") 
                     .-value)
        form-data (generate-form-data 
                    {"page" page-name
                     "data" new-data})] 
    (js/console.log "SAVING")
    (js/console.log (str new-data))
    (.send XhrIo
      "/clj_ts/save"
      (fn [e] e)
      "POST"
      form-data)))

Now I can see from my browser's developer tools that I am POSTing up something with form-data that contains values for page and data.

But in my server-side code, the :form-params of the request is empty.

What am I missing or doing wrong?

1

There are 1 best solutions below

1
On

I always use the library cljs-ajax instead of direct JS interop. Then you can do something like:

; Post a transit format message
(POST "/send-message"
        {:params {:message "Hello World"
                  :user    "Bob"}
         :handler handler
         :error-handler error-handler})

They also have explicit FormData support:

; Send file explicitly, ClojureScript specific
(let [form-data (doto
                    (js/FormData.)
                  (.append "id" "10")
                  (.append "file" js-file-value "filename.txt"))]
  (POST "/send-file" {:body form-data
                      :response-format (raw-response-format)
                      :timeout 100}))

Their README is pretty straightforward.