Fork me on GitHub
#beginners
<
2016-03-13
>
bwstearns03:03:45

Can someone help me for a minute with figuring out a compojure/reagent problem?

bwstearns03:03:40

I'm getting back {:id 2, :title "foo"}{:id 3, :title "bar"} as the body of a response, but it's being recorded as a string and not json

bwstearns03:03:56

The request is responding with the following route at handler.clj: (GET "/titles" [] {:body (all-titles) :format :json}) and is called with the following cljs-ajax request: (GET "/titles" {:handler titles-handler :format :json}))

mkaschenko05:03:06

Hello clojurians. I'm doing clojure koans at the moment. Can someone tell me what is wrong here:

(defn recursive-reverse [coll]
  (if (empty? coll)
    coll
    (conj (recursive-reverse (rest coll)) (first coll))))

(recursive-reverse `(1 2 3)) # => (1 2 3)

mkaschenko05:03:21

My expectation is (3 2 1)

codonnell06:03:15

@mkaschenko: if you conj onto a list, it adds to the front.

maxov06:03:44

hello @bwstearns, I’ve tried to find the :format keyword but couldn’t find any usage in compojure or ring, do you know what library uses it?

bwstearns06:03:30

@maxov I saw here: http://yogthos.net/posts/2013-04-09-Introducing-cljs-ajax.html I didn't see it in the compojure side at all, but I just tried it because I'm out of ideas and it didn't error.

bwstearns06:03:24

@maxov: I've also tried it without but the frontend still stores it as a string

maxov06:03:59

ok, :format is used by cljs-ajax on the client side for the format of the body, but it isn’t used anywhere in your backend stack

bwstearns06:03:01

Is the fact that the keys are clojure keywords in the message body possibly the reason?

maxov06:03:23

I’d recommend wrapping your routes with a library that handles json, probably https://github.com/ring-clojure/ring-json is best

bwstearns06:03:58

My middleware looks like:

(defn wrap-middleware [handler]
  (-> handler
      (wrap-defaults api-defaults)
      wrap-exceptions
      (json-middleware/wrap-json-body {:keywords? true})
      json-middleware/wrap-json-response
      wrap-reload))

bwstearns06:03:44

which I thought should have been producing the JSON responses correctly

maxov06:03:00

well, you don’t need the :format keyword on your backend first off

bwstearns06:03:08

Removed that.

maxov06:03:08

I’m not sure why it’s still responding with EDN — it seems like you’re using ring-json correctly

bwstearns06:03:23

Ohhhh, that's why it looks like clojure keywords?

bwstearns06:03:45

I've been putting off going and learning about EDN until after I figured this out..... I'm a damned idiot haha.

maxov06:03:23

yes. edn is a data transport format very similar to json that’s basically just clojure data structures

bwstearns06:03:42

note to self: read the whole internet before proceeding.

bwstearns06:03:16

ok, so the problem is then likely to be server side somewhere because the data isn't being encoded in JSON?

maxov06:03:44

I think so

maxov06:03:00

could you elaborate what you mean by ‘recorded as a string and not json’ on the front end

bwstearns06:03:50

So, the call looks like this:

(defn pieces-handler [pcs]
  (swap! app-state assoc :all-pieces pcs))

(defn fetch-pieces []
  (GET "/art/pieces" {:handler pieces-handler :format :json}))

bwstearns06:03:25

the js->clj bit was kinda like the :format on the server in that it wasn't there most of the time it was kinda of a shot in the dark

bwstearns06:03:12

Huh, something I changed on the backend as a result of our conversation apparently flipped the right bit because it's not coming over the wire as EDN anymore

bwstearns06:03:42

ok so now the problem must be that I'm not converting the received JSON into a cljs map right?

bwstearns06:03:26

oh, sorry I got sidetracked. There is a component that makes a list from the pieces in :all-pieces. Right now there should be 5, and its producing 143 with nils for fields because apparently :all-pieces is a string so it's iterating over each letter

maxov07:03:57

what does pcs look like

bwstearns07:03:31

stagistry.core=> (:all-pieces @app-state)
"[{\"id\":2,\"title\":\"foo\",\"description\":\"bar\",\"price\":5,\"artists_id\":null},{\"id\":3,\"title\":\"foo\",\"description\":\"bar\",\"price\":5,\"artists_id\":null},{\"id\":4,\"title\":\"The Silence of the Lambda\",\"description\":\"Something something java beans and a nice chianti\",\"price\":5000,\"artists_id\":null},{\"id\":5,\"title\":\"The Silence of the Lambda\",\"description\":\"Something something java beans and a nice chianti\",\"price\":6000,\"artists_id\":null}]"

bwstearns07:03:28

I tried adding json-response-format to the GET call: (GET "/art/pieces" {:handler pieces-handler :json-response-format {:keywords? true}}))

maxov07:03:24

the format is supposed to be detected automatically from the content-type header

maxov07:03:43

try adding in :response-format :json to the options map for the GET

bwstearns07:03:56

Still coming in as a string.

bwstearns07:03:09

(GET "/art/pieces" {:handler pieces-handler :json-response-format {:keywords? true :raw false} ::response-format :json})

bwstearns07:03:06

Oh wow. that worked. the only difference from perfect is that the keys are strings not keywords, which is probably what I missed all those errors ago and how I ended up with a string instead of a map.

bwstearns07:03:39

@maxov thanks so very much.

maxov07:03:19

no problem

bwstearns07:03:13

Sorry for the somewhat spazzy description of the problem, it's one of those things where I had pretty much run out of ideas and so there were likely several places where I had started to actively impair my odds of success as opposed to get closer to the answer.

mkaschenko07:03:35

@codonnell: thank you

chadhs18:03:16

i’m dealing with a cyclical dependency issue

chadhs18:03:14

i had a few middleware functions in a core.clj file, and decided to move them to a middleware.clj and important them into core.clj with a :refer statement

chadhs18:03:52

one of the functions called wrap-db uses the value of db which is just a def statement in core.clj

chadhs18:03:08

i’m wondering how i can keep that middleware function out of my core.clj but still ref that db value from core

chadhs19:03:06

answered my own Q, this problem seem to indicate a poor design choice on my part.

chadhs19:03:00

i should perhaps move my db connection config elsewhere

lmergen19:03:08

yes it usually is, most often you have to get back to the drawing table and reconsider the bigger picture

sveri20:03:43

@chadhs: @lmergen I had good success with: https://github.com/timmc/nephila when this happened to me

chadhs20:03:57

@sveri that’s cool