Question

I have a home page being rendered that requests user-input as vectors of integers. I need those data-structures, because they play nice with the math functions that I will use to manipulate the input:

(defn home [& [weights grades error]]
  (html
    ;; ...
   (form-to [:post "/"]
    ;; ...
    (text-area {:rows 15 :cols 30 :placeholder
"[89 78 63]
                    [78 91 60]
                    [87 65 79]
                    ..." } "grades" grades)]
     (submit-button "process"))]))

And the "process" button sends the input through a defroutes function, using a POST method, which calls a processed method that renders html showing calculated results from the input. The function being used to calculate the final list of grades is called process-grades. I am trying to use read-string to change the input data-structures into something that my function can handle, but cannot make it work. When I replace the call to processed with "TEST", I have no trouble rendering the text after hitting the process button:

(defn process-grades 
  "Takes user input from home's form-to function and processes it into the final grades list"
  [weights grades]
(->> grades
     (map (partial percentify-vector weights))
     (mapv #(apply + %))))

(defn processed [weights grades]
  (cond
   (empty? weights)
   (home weights grades "You forgot to add the weights!")
   (empty? grades)
   (home weights grades "You forgot to add the grades!")
  :else
  (do
  (html  
   [:h2 "These are your final grades."]
   [:hr]
   [:p (process-grades (read-string weights)(read-string grades))])))) ;; <- This is not working!


(defroutes grade-routes
           (GET "/" []
                {:status 200
                 :headers {"Content-Type" "text/html"}
                 :body (home)
                 })
           (POST "/" [weights grades] (processed weights grades))
           (ANY "*" []
                (route/not-found (slurp (io/resource "404.html")))))

I have done a bit of research on the html form tag, Clojure's read-string function and various ways of scripting the functionality that I need. With a glut of information I am still left wondering: what is the simplest, most concise, idiomatic way to do this? Should I reach for Clojurescript or can I use Vanilla-flavored, JVM Clojure here?

Was it helpful?

Solution

You're getting an error because (process-grades) is returning a vector of numbers, which means that the form below

[:p (process-grades (read-string weights) (read-string grades))]

will end up looking like the following (once process-grades has returned):

[:p [4/5 3/2 6/3 ... more numbers]]

Hiccup only knows how to handle keyword html tags at the beginning of each hiccup vector, so it will complain about this loudly.

Eventually you'll need to format the output nicely in the way you want, but for the time being you should be able to get it running by wrapping the (process-grades ...) call in (apply str) to turn the vector into a string.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top