I’m just starting out with clojure and I’m doing a project for fun. In the below function I’m just trying to display some blog posts (with some options). With the “as” option, I want to give the client code the ability to choose between vector [] and map {}. I had this working when I only had (into [] results), but as soon as I put the (when) statement in, it stopped working. I guess (when) just returns nil because it’s like an implicit (do). It’s obvious to me now that using (when) at the end like this is the wrong way to end a function you expect to return a value. How do I get this to work?
(ns yf.models.post
(:require [clojure.java.jdbc :as sql]
[clojure.string :as str])
(:use [yf.models.helpers :only [date-format]]))
(defn all [& {:keys [order limit roots-only as]}]
(sql/with-connection (System/getenv "DATABASE_URL")
(sql/with-query-results results
[(str
"SELECT
id,
body,"
(date-format "created") ","
(date-format "modified")
"FROM post a"
(when (true? roots-only)
" WHERE NOT EXISTS (SELECT child_id from post_map b
WHERE a.id=b.child_id) ")
(when (and
(string? (order :column))
(string? (order :dir))
(or
(= (:dir order) "asc")
(= (:dir order) "desc")))
(str " ORDER BY a." (:column order) " " (:dir order)))
(when (and
(instance? Number limit)
(pos? limit))
(str " LIMIT " limit)))]
(when (and ;this is where the problem is
(string? as)
(not (str/blank? as)))
(when (= as "vector")
(into [] results))
(when (= as "map")
(into {} results))))))
The problem isn’t that
(when)always returnsnil–it doesn’t always returnnil; it returns whatever is last in the collection of expressions.(when)is a macro that uses ‘(if)and(do)and that’s exactly what(do)does: executes a list of expressions and returns the value of the last one in the collection.I tried the
(case)macro instead and it works:Or, better (thanks kotarak):
where
asis likevector(as opposed to"vector", I think)