This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-12-24
Channels
- # adventofcode (25)
- # asami (39)
- # beginners (39)
- # biff (12)
- # clojure (53)
- # clojure-dev (4)
- # clojure-europe (6)
- # clojure-hungary (1)
- # clojure-norway (4)
- # clojure-spec (3)
- # conjure (2)
- # cursive (1)
- # dev-tooling (9)
- # emacs (4)
- # introduce-yourself (2)
- # juxt (4)
- # membrane (8)
- # off-topic (3)
- # polylith (8)
- # portal (4)
- # releases (1)
- # scittle (9)
- # sql (11)
- # squint (5)
- # xtdb (12)
What am I doing wrong here?
(let [myvar 1] myvar)
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: myvar in this context
OK I quit clojure and re-opened it and now it works
dw thats why
Lispers hold inalienable the right to shoot off our own toes. Welcome to the club.
Hi all. I think I'm just missig some obvious thing. What I'd like to achieve is essentially
curl -d '{"A": "huhu"}' "
{"A" "huhu"}
I'm trying to achieve this with:
(defn add-question [request]
{:satus 200
:headers {}
:body (generate-string (:params request))})
(defroutes app-routes
(GET "/" [] "Hello World")
(POST "/api/srv/question" [] add-question)
(route/not-found "Not Found"))
(def app (-> app-routes
(wrap-params)))
while generate-string comes from chechire https://github.com/dakrone/cheshire
but the result I get is:
curl -d '{"A": "huhu"}' ""
{}%
What am I missing?(ns server
(:require cheshire.core
[compojure.core :refer [defroutes GET POST]]
[compojure.route :as route]
[ring.adapter.jetty :as jetty]
[ring.middleware.json :refer [wrap-json-response wrap-json-body]]
[ring.middleware.params :as params]))
(defn add-question [request]
{:satus 200
:headers {}
:body {:body (:body request)
:params (:params request)}})
(defroutes app-routes
(GET "/" [] "Hello World")
(POST "/api/srv/question" [] add-question)
(route/not-found "Not Found"))
(def app (-> app-routes
params/wrap-params
wrap-json-response
wrap-json-body))
(comment
(def server (jetty/run-jetty #'app {:port 4000 :join? false}))
(.stop server)
)
i’ve added a few other things here. wrap-json-response
will make maps returned be serialized into json. and wrap-json-body
will parse the body of requests with an application/json content-type into a clojure datastructure
and the crux of it is that you are sending the data over as the body of the request. It’s not a parameter of the request
❯ curl --data '{"A": "huhu"}' --header 'Content-Type: application/json' ""
{"body":{"A":"huhu"},"params":{"params":"here"}}%
I’m returning a map with two keys:
• "body"
: This has the payload sent over
• "params"
this has the params from the route. (note my route is api/srv/question?params=here)
deps required for these:
{:deps {ring/ring {:mvn/version "1.9.6"}
compojure/compojure {:mvn/version "1.7.0"}
ring/ring-json {:mvn/version "0.5.1"}
cheshire/cheshire {:mvn/version "5.11.0"}}}
FYI what you are destructuring in add-question
(before @U11BV7MTK changes) are the query parameters passed to the URI not the body of the request (sent in the cURL -d option). So if you did this:
curl -X post ""
{"A":"huhu"}
You would see the expected results.The query params are key value pairs following the ?
I believe it also includes route params. Like if your route was api/srv/question/<question-id>
you would have the question id in the params map as well
Ok, thank you very much @U11BV7MTKand @U05390U2P you helped me a lot here. I cannot tell you, why I missed something here, or what it was. I also was aware that params and body are diffferent things, but ring-documentation was a bit confusing in some paragraphs... any, I struggeled, because I constantly got an
:body #object[org.eclipse.jetty.server.HttpInputOverHTTP 0x
5f126a6c HttpInputOverHTTP@5f126a6c]
why is it gone now? and how could I handle a inputOverHttp, seems to be a stream, also tried to play around with io/stream-reader... you see I dived in a big sea there 😄
but maybe it also was a side-effect of using wrap-defaults with site-defaults.... have to dig around a bit
I tried a lot there, also using api-defaults http://et.al.
~Hi - question about `line-seq` -- this just appears to hang my repl and I'm unable to interrupt evaluation when I invoke it with something like `(count (get-lines "~/tmp/blah.dat"))` . This file is outside of my project directory if that matters.~ ```(defn get-lines [file-pathname-string] (with-open [rdr (io/reader file-pathname-string)] (line-seq rdr)))``` ~What I think I am doing here is returning a lazy sequence of lines from this file that I could then use else where. Is that actually what I am doing?~ It is paredit messing with my repl. NEVERMIND
actually - the code above seems to consistently result in an IOException "stream closed" in the repl. I know that passing the line-seq to something like doall
should make it work but that defeats the purpose of the sequence, no? Is it possible to use line-seq
on an io/reader
result lazily?
If you macroexpand with-open
, you'll see that it will close the reader before the function returns.
(clojure.core/let
[rdr (io/reader file-pathname-string)]
(try
(clojure.core/with-open [] (line-seq rdr))
(finally (. rdr clojure.core/close))))
If you want to read after the function returns, then you can't use with-open
. However, if you don't use with-open
, then you want some way to clean up at the right time (whenever that is).It's usually fine to use doall
in cases like these. The main exception is if the file is large and you don't want to hold the full contents of the file in memory. In those cases, you can do as @U6T7M9DBR suggests and do the processing inside.
I think processing a file line by line is a good use case for transducers. something like:
(defn transduce-lines [xform f init fname]
(with-open [rdr (io/reader fname)]
(transduce
xform
f
init
(line-seq rdr))))
;; count characters
(transduce-lines
(map count)
+
0
(io/file "deps.edn"))
I was just thinking on the drive home whether or not I could use a transducer here. That seems like a good approach
you don't need a transducer, even though it may be the better solution. to me the main idea in the transducer code is that you are processing the whole file in the fn, and one of the params is the transformation/behaviour. you can do this with or without a transducer, just make sure that your file processing function follows the same guidelines.
Hmm, I guess it’s better to post noob questions here, than the Clojure/ClojureScript channels.
Yes, you'll get more polite and more in-depth answers here as folks have opted in to helping folks who are new to Clojure/Script.
Can someone help me understand why empty?
doesn’t work in functions like map, filter
(empty? '()) => true
filter empty? '((1, 2, 3), (), (4, 5, 6)) => '((1, 2, 3), (), (4, 5, 6)) ; Doesn't filter the empty list items
I think you're missing some parens and it's just returning the last form
What are some good online Clojure REPL’s that I can use to share code? 😄 Currently, the only one that I’m aware of is Replit