Jason Basanese
Jason Basanese

Reputation: 720

How to execute a database entry based on a html form post in clojure?

I am working with Compojure and ran into a problem with the macro "defroutes". My error is caused by the macro not evaluating a function. Here is an example of my routes and what I'm trying to do. Stars added for emphasis.

(defroutes simple-routes
  (GET "/", [],  form)
  ***(POST "/", [count, day], (do (create-entry count day) "Success!")***
  (GET "/attendance/", [], response)
  (resources "/")
  (not-found "404")

create-entry functions correctly when evaluated as such (create-entry 1 2) Inputting the two integers into the database. However it does not get run when placed in the above route macro. What could I do to get the two integer values from an html form post to be run as (create-entry count day)? (yes I know this code is not stand alone but the above code is the only code in question, as everything else runs fine.)

Upvotes: 0

Views: 63

Answers (2)

Piotrek Bzdyl
Piotrek Bzdyl

Reputation: 13185

You can use Compojure binding of form params along with params coercion:

(ns compojure-hello-world.handler
  (:require [compojure.core :refer :all]
            [compojure.route :as route]
            [compojure.coercions :refer :all]
            [ring.middleware.params :refer [wrap-params]]))

(defroutes app-routes
  (GET "/" [] "Hello World")
  (POST "/" [count :<< as-int
             day   :<< as-int]
              (println "Count" count (type count) "Day" day (type day))           
              (create-entry count day)
              {:status 200 :body "Done"})
  (route/not-found "Not Found"))

(def app
  (-> app-routes (wrap-params)))

Then you can test it:

curl -X POST --data "count=1&day=2"  http://localhost:3000/

Upvotes: 2

Jason Basanese
Jason Basanese

Reputation: 720

There is certainly a more concise method. However changing the starred line to the following, and adding a function, works:

(POST "/", [], entry) 

entry will be passed a map of the form post. The following is an atrocious function designed to get the values out of said map and pass them to create-entry:

(defn entry [request]
  (apply create-entry (reduce #(conj %1 (Integer/parseInt (get (get request :params) %2))) [] '(:count :day))))

This stands as a patch until someone who has been working with this for longer can give a better answer.

Upvotes: 0

Related Questions