This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2017-11-22
Channels
- # aws (1)
- # beginners (102)
- # boot (5)
- # cljs-dev (59)
- # cljsjs (1)
- # clojure (154)
- # clojure-australia (1)
- # clojure-brasil (1)
- # clojure-dusseldorf (4)
- # clojure-greece (36)
- # clojure-italy (10)
- # clojure-poland (5)
- # clojure-romania (1)
- # clojure-russia (7)
- # clojure-spec (32)
- # clojure-uk (113)
- # clojure-ukraine (3)
- # clojurescript (107)
- # cursive (13)
- # data-science (25)
- # datomic (23)
- # emacs (3)
- # events (1)
- # fulcro (72)
- # funcool (10)
- # graphql (1)
- # leiningen (1)
- # luminus (2)
- # lumo (38)
- # off-topic (14)
- # onyx (78)
- # planck (4)
- # re-frame (55)
- # reagent (1)
- # ring (3)
- # ring-swagger (2)
- # rum (19)
- # shadow-cljs (89)
- # spacemacs (101)
- # sql (2)
- # unrepl (88)
@tvalerio hm, I think it's not working, still debugging:
(-> (ok {:x y)
(assoc "headers" {"content-type" "text/html"}))
Content-Type: application/json; charset=utf-8
this is weird, I've checked that I'm setting the header where the route is defined, and turned off all middleware, but the header is still reverting to "application/json"
the above isn't even valid code, so maybe start there before dumpling all the handlers and middlewares
(it helps to use the ring.util.response
functions to make sure you're creating valid responses)
@hiredman apologies, I've mostly been using (content-type "text/html")
and @seancorfield thanks, ya that fn is in ring.util.response
and https://github.com/ring-clojure/ring-json/blob/master/src/ring/middleware/json.clj#L103-L112 clearly shows it doesn't check Content-Type at all to determine if it needs to encode
the docstring here https://github.com/ring-clojure/ring-json/blob/master/src/ring/middleware/json.clj#L114-L128 says it only encodes vectors or maps
https://github.com/ring-clojure/ring-json/blob/master/src/ring/middleware/json.clj#L107
@josh.freckleton And what exactly is your ok
function doing?
just returns a simple map (`ring.util.http-response/ok`)
(defn ok
"200 OK (Success)
OK"
([] (ok nil))
([body]
{:status 200
:headers {}
:body body}))
Using your ok
and ring.util.response/content-type
and ring-json
's ring.middleware.json/wrap-json-response
seems to work as expected: https://www.dropbox.com/s/dzts47q5bwpg59x/Screenshot%202017-11-21%2016.57.17.png?dl=0
The (assoc "headers" ...)
you had before, definitely would not work (as @hiredman said) because it uses a string instead of a keyword.
And even if you used :headers
, you need to capitalize the header name for it to work.
Anyways, did you get it sorted out in the end? Or are you still looking for input? @josh.freckleton
haha, thanks, and no I'm still at it, brute forcing a bit
(-> (ok (str {:recording-url signed-url}))
(assoc "Header" {"Content-Type" "text/html"})
(assoc "Headers" {"Content-Type" "text/html"})
(assoc "Content-Type" "text/html")
(assoc :Header {"Content-Type" "text/html"})
(assoc :Headers {"Content-Type" "text/html"})
(assoc :header {"Content-Type" "text/html"})
(assoc :headers {"Content-Type" "text/html"})
(content-type "text/html"))
FYI you only need one assoc call there, it’s vararg
as I pointed out in the link to the code, setting the content-type to "text/html" or anything else, will not effect wrap-json-response
If you set :headers {"Content-Type" "text/html"}
then wrap-json-response
will not overwrite that -- as I showed in my screenshot.
@josh.freckleton Your code has weird indentation!
oh sorry, it's indented where it is, and when I paste it, I'm missing the whitespace before the first open paren
Ah, ok 🙂
and re your help, thank you, it must be something else in my code, I think I'll attack it tomorrow with fresh eyes
But, anyway, as I showed in the REPL session above, (-> (ok {...}) (content-type "text/html"))
will "do the right thing" in that you'll get your desired content type and still get a body that is the JSONification of the data structure.
(so perhaps I'm not understanding what you're trying to do?)
well, i'm trying the same code as you, but within a big code base, and for some reason that Content-Type: text/html
is getting replaced with Content-Type: application/json
I'm sure it'll be surprisingly simple when I find it :face_with_rolling_eyes:
Er, I thought you wanted it the other way around?
yes, oops (fixed)
I'd write a little debugging middleware function that displayed a message and the content type and thread that into your stack of middleware in between each layer.
that's a good idea, that'll be a good place to stage round 2 of this battle 🙂
Middleware can be pretty sensitive to ordering -- so I tend to rely on the ring-defaults library for the basic stack.
when using predicates with clojure spec, is there a way, instead of just returning true/false, also return a error msg on false ?
I can't do #(apply and %)
since and
is a macro. What is the idiomatic way to logic-and a list ?
every?
?
(every? identity coll)
would work
About middleware ordering, I have been playing with middleware as data, just like Pedestal interceptors. I think we can solve most of the middleware ordering / debugging problems with data and a mw-composer. Plan: instead of just functions, mw are maps with :wrap
key with the actual mw-function. In addition, they can have things like :name
, :spec
, :produces
and :requires
. Middleware-chain is vector of maps, which is composed into actual mw-function by the a composing function producing zero runtime penalty. The intermediate mw data format allows things like documentation extraction, automatic/manual re-ordering, adding debug-mw’s between all mw’s in dev etc.
we are building up a new routing library, which supports this (for both mw & interceptors), but I’m wondering could it be a more general solution for Ring in the future? ping @weavejester.
And @josh.freckleton there is also Muuntaja, which does JSON content negotiation like ring-json, but also for other formats too (EDN, Transit). It has a lot of options that the endpoint can set to override the defaults. One can change just the response content-type, request a different response encoding, or disable the response encoding totally, see https://github.com/metosin/muuntaja#response. c-api 2.* uses this internally.
When I'm working with XML and zippers, is there any way to tell if the point I've got to in the zipper is an Element (as opposed to a string or whatever) without converting to a node first?
At the moment I'm doing (instance? clojure.data.xml.node.Element (zipper/node location))
. (map? (zipper/node location))
also works for the cases I care about because an element is a map and other things aren't, but it'd be nice if there was some way I could do (element? location)
without having to convert to a node myself
hi guys - what is the simplest way in a Clojure server to start new threads for some async processing? Preferably with threadpools, like using Java's ExecutorService
. I am not expecting any return value from the submitted task. future
seems tempting but I'm afraid that they are not cleaned up if I'm not dereffing them. Is there a convenient way achieving this? Or shall I use some interop to use Java ExecutorService with fns?
@andras.liter what do you mean by not cleaned up ?
Hi @U053XQP4S I mean that the thread will remain in the memory, its stacktrace will consume the available stack and if I end up having too many, I could run out of memory
future
basically wraps the body in a fn
and submits it to a unbounded thread pool Executor. If you don't use the result it will be candidate for GC as soon as it's done and the thread will likely be reused for subsequent computations
if you're familiar with java executors you should have no surprise with clojure.core future
https://github.com/clojure/clojure/blob/clojure-1.9.0-alpha14/src/clj/clojure/core.clj#L6838
thanks, awesome
@andras.liter beware though, that you might hit some surprises, especially with exception handling (exception invisible until you deref the future - unless you wrap the future body with try-catch explicitly). Check also https://github.com/TheClimateCorporation/claypoole
@andras.liter https://github.com/ztellman/manifold uses an ExecutorService and will be there when you do need to use the return values 🙂
is there any disadvantage to using gensym
for making up arbitrary keys? my use case is that i have a list of strings and i want to remove certain ones after a pause. since strings can be duplicated i need to assign them some sort of identifier.
(with the understanding that gensym won't be unique across different instances of the same app, of course)
Yes, executor here http://aleph.io/codox/manifold/manifold.executor.html
also cljs version https://github.com/dm3/manifold-cljs
🙂 after a long while away from clojure, could someone benevolently remind me how do I stream process a file? e.g. reading one text line at a time without ever storing the entire file in memory?
Thanks guys. I must have encountered a severe form of programmer amnesia... even this simple adaptation of that source code which I was trying before posting here doesn't work for me
(with-open [rdr ( input-file-name)]
(map
println
(line-seq rdr)))
meaning:
(with-open [rdr ( input-file-name)]
(doseq [line (line-seq rdr)] (println line)))
but then again, if your real use case isn’t about doing side-effects then probably map is just fine
possibly because I’ve never actually used that 🙂 And it came in 1.7 it seems, wayyy too new stuff for me :oldman:
Hi. Some one uses incanter? It shows empty windows instead of graphs. I tried to set different versions of it and clojure in project.clj. Also changed jdk7 to jdk8. Can't solve problem
This problem appears also on another computer, what I have
I found out what this happent when my wm is bspwm. With xfwm4 all works as intended...
Another apps on java awt and swing works fine
Where I should I write an issue? In bspwm repo or incanter repo?
Any idiomatic way of verifying a sequence is lazy? (e.g. in test code, or as an assertion)
I wish to make sure I've not accidentally yielded an unlazy collection after a lot of collection manipulations
Otherwise my program would realize huge collections whereas it is supposed to do streaming work, to maintain a constant memory footprint
Note that a LazySeq is usually Chunked anyway - check into transducers or core.async + transducers if you really want to do streaming work
nit: LazySeq is never chunked, it is possible that the underlying seq it wraps is chunked, but LazySeq itself knows nothing about chunking
They evaluate a chunk of themselves (32 or so) items eagerly, for performance reasons.
i'm not sure how you could check this in general though. something could be fully realized and also a clojure.lang.LazySeq
@dpsutton there must be a way to know whether the type is lazy, regardless of its current state (realized or not)
well lazyseq is a container amenable to lazy realization. but it does not change into a different type upon full realization
i guess so. but if the assertion is not falsifiable it does not introduce any confidence.
well my point is to make sure a collection does not arrive at a certain function not lazy
that would certainly be true, if something comes in as a vector is is guaranteed to be fully realized. the problem is that if something comes in as a LazySeq it is not guaranteed to not be realized
@matan Do you mean something like this:
(let [x (map inc [0 1])]
[(realized? x)
(first x)
(realized? x)])
care to elaborate how flawed laziness is though? "esp given that the clojure never guarantees how lazy things are"
@matan it's really easy to go from 1-el-at-a-time to chunk-at-a-time laziness in clojure
@tobias994 come to #beginners and we'll dig through it
because clojure makes no guarantees about the laziness granularity and it's free to use what's more performant
@bronsa what's wrong with chunks? a chunk of 32 is orders of magnitude smaller than e.g. a file with million lines... it will guarantee 32 lines in memory at a time, compared to a million lines had the entire file been realized
but if your element is not an atomic value but a big expensive collection, then you might not have space for 10 elements in memory
again, it depends on what you need to do, but if you're aiming to build a streaming pipeline, reach for transducers which were designed for that (among others) use-case in mind
well indeed, next time I'll start with transducers, but for my simple use case this once, it seems laziness is enough, given the issue (in my use case) is collection size, not element size
How do I open cider inspector with value of last expression evaluated while stepping? I tried cider-inspect
but it does nothing
Anyone here have much experience with https://github.com/oliyh/martian? I am trying to get the martian/bootstrap method working with a simple get request. Here's a simplified version of what I am seeing:
;Works
(client/get "" {:query-params {:arg 1}})
;Fails
(let [m (martian/bootstrap
""
[{:route-name :myservice
;Is this for path params? If so, how would I do query-params?
:path-parts ["/myfunction/" :arg]
:method :get
:path-schema {:arg s/Int}}])]
(martian/response-for m :myservice {:arg 1}))
I can't seem to get the martian version to work. Any ideas? It seems like I should be specifying query-params instead or something like that.FYI: I've tried a variety of different options like
;Fails
(let [m (martian/bootstrap
""
[{:route-name :myservice
:path-parts ["/myfunction/"]
:query-params [:arg]
:method :get}])]
(martian/response-for m :myservice {:arg 1}))
I've also tried a :path key, and others. No dice.is there a way to add dependencies to my project.clj
without visiting github all the time and copying package name + version ?
@bravilogy The only thing I've seen like that is this leiningen plugin: https://github.com/johnwalker/lein-plz
thank you @jaysherby