This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-12-11
Channels
- # adventofcode (116)
- # aleph (10)
- # announcements (2)
- # beginners (67)
- # boot (3)
- # calva (17)
- # cider (8)
- # cljdoc (27)
- # cljsrn (6)
- # clojure (144)
- # clojure-austin (3)
- # clojure-boston (1)
- # clojure-dev (25)
- # clojure-europe (4)
- # clojure-italy (26)
- # clojure-losangeles (4)
- # clojure-nl (28)
- # clojure-russia (1)
- # clojure-uk (34)
- # clojurescript (130)
- # cursive (20)
- # datomic (69)
- # emacs (14)
- # figwheel-main (2)
- # fulcro (31)
- # graphql (3)
- # hyperfiddle (3)
- # jobs (1)
- # jobs-discuss (1)
- # kaocha (1)
- # leiningen (2)
- # lumo (2)
- # nrepl (1)
- # off-topic (182)
- # onyx (5)
- # re-frame (88)
- # reagent (12)
- # reitit (2)
- # ring-swagger (13)
- # shadow-cljs (136)
- # tools-deps (28)
- # vim (4)
Suppose you have filters in the page which would be nice to update the url automatically
How are people doing that kind of things? Is there any helper library that just takes a bunch of filter subscriptions and makes sure the url is always in sync?
@U0524T275 I don’t know if there’s an easier way, but I’ve got an example I struggled through up on github: https://github.com/rgm/bidi-pushy-example/
The example is trying to keep clicked links (representing a search, eg. `?s=my+search), a change to an on-screen text input, and a full-page reload (ie. cold-starting your SPA from eg. an emailed search link) all lined up. I’m not sure I’ve done it all right; I’m finding it tricky.
Thanks I'll have a look
additionally, is it possible to send the file contents as part of a map, like so {:file file :filename filename}
?
i've been trying different things but either due to incorrect client setup or middleware what comes out of the request server-side is unusable
You’re using a file
input field to get the file contents?
`[:input {:type "file" :on-change #(dispatch [:upload-file (aget (.. % -target -files) 0)])}]`
that ought to send the file itself through to the :upload-file
event in my estimation
Ok, and in the event handler, if you js/console.log
the incoming argument, it’s the file you’re expecting, correct?
yes, at least I think so. it's a javascript object with keys like name
type
lastModified
etc.
I’m looking at the cljs-ajax docs at https://github.com/JulianBirch/cljs-ajax:
; Send file explicitly, ClojureScript specific
(let [form-data (doto
(js/FormData.)
(.append "id" "10")
(.append "file" js-file-value "filename.txt"))]
(POST "/send-file" {:body form-data
:response-format (raw-response-format)
:timeout 100}))
:thinking_face:
I haven’t done file uploads in re-frame, but I can play with it and see if I can get a working version.
it might be that some ring middleware is interfering also, but I don't really see how
and I'm also confused by the method of putting file contents in the body
directly, as other examples talk about using multipart-params
for this (which I've also tried, but then the request isn't even sent, seemingly due to incorrect request format)
Ah, I would guess that :request-format (ajax/json-request-format)
is not right for this situation.
That’s going to try to coerce your file data.
i thought so too, but it turned out to not matter, at least not so far with whatever my problem is
i'm using compojure
to handle the requests; (POST "/file" {body :body} (response (sql/insert-file! jdbc {:file body :filename ""})))
On the server side, are you including the ring multipart params middleware?
but the body is just a #object[org.eclipse.jetty.server.HttpInputOverHTTP 0xdf9085 HttpInputOverHTTP@df9085[c=12876,q=0,[0]=null,s=EOF]]
, with no apparent way to parse it
Ok, that org.eclipse.jetty.server.HttpInputOverHTTP object is what the multipart-params middleware should be processing for you, so I’m going to guess that you actually have the client side working correctly, and just need to figure out why the server side isn’t pulling out the file.
(I’m basing my guess on this SO post: https://stackoverflow.com/questions/42829594/how-to-get-the-content-of-httpinputoverhttp-in-clojure-compojure-ring-project)
There’s also this: https://stackoverflow.com/questions/37397531/ring-read-body-of-a-http-request-as-string
If I were debugging this, I might try uploading a plain text file (so that when I decode it, it’s not a bunch of binary gibberish), and then use the (ring.util.request/body-string request)
trick to see what’s coming down to the server.
according to this https://github.com/ring-clojure/ring/wiki/File-Uploads
"This adds a file key to the :params map of the request where :tempfile is a java.io.File object that contains the uploaded data. You can use this to perform any further processing you want."
as not a http wiz this has me confused. i put the file in :body
in the outgoing request, but the parsed version is found in :params
?
The reference to the :params
map is referring to middleware processing that Ring does on the server side. What’s supposed to happen is that the request arrives at the server with the uploaded file in the :body
of the request, as an HttpInputOverHTTP object. The middleware then reads the file data out of that object and stores it in a temp file, and puts a key in the :params
map, where the name of the key is (I think) the key that you sent your file under, and the value is an input stream for the temp file on the local filesystem. So by the time your request handler receives the request, all this has happened, and your handler should be able to just look for the temp file under the :params
key in the request map.
all I can guess then is that for some reason wrap-multipart-params
is not kicking in, since I clearly still have the HttpInput object as :body
after all the middleware
which brings me back to; what could be wrong in my HTTP request config (after discarding json as :request-format
)
or, i mean, i don't have the parsed contents in :params
. I guess :body
will be left untouched
Yeah, my suspicion is that you need to set :request-format to something explicit that says you’re sending multipart form data
if so it must be a re-frame
specific thing, because ring
doesn't seem to require that
Hmm, I wonder what’s being passed as the Content-Type, can you check the :headers in the request?
I’m fairly certain you need to set multipart/form-data or similar for file uploads to work, but I’m on a phone and can’t double check :)
this exampel https://stackoverflow.com/questions/37397531/ring-read-body-of-a-http-request-as-string works just find as long as you pass a pure text file
but the funny part is, I have to remove wrap-params
and wrap-multipart-params
for that to work
Ok, everything looks to me like the browser side is doing everything it’s supposed to.
When you have the multipart params middleware in place, are you getting anything in the request’s :params
key?
i added a log to the last level of middleware, and there's no :params key in the request at all
Maybe the multipart middleware is in the wrong place? Too early or too late?
Seems like it has to be something on the server side.
i already tried removing all other parsing middleware except wrap-multipart-params
to no avail
Though just to double-check, you are doing the part where you encode the file data using
(doto
(js/FormData.)
(.append "id" "10")
(.append "file" js-file-value "filename.txt"))
correct?but yeah sending it as js/FormData
does the trick, at least in this specific case (with then the FormData
as request body)
Awesome, alls well that ends well, I always say. (Mainly because I’ve been bitten by this sort of thing more than once myself)
and now of course the middleware parses everything out to a handy map with :tempfile
and :filename
keys
Cool, glad to hear it because I think I’m eventually going to have to add file uploads to the project I’m working on.
So now I’ve got some experience working with it.
Yeah, it’s nice having a lot of documentation but there’s also the converse problem of knowing where to focus your attention.
meaning if you're using the re-frame
client you really should read the cljs-ajax
docs as well
Yeah. And in some cases, read source code too.
Though on the plus side I’ve generally found Clojure to have the most readable source code of any language I’ve ever worked in, due to the inherent simplicity.
Yeah, it’s not impossible to write obfuscated Clojure, but it does lend itself to writing clear code when you know what you’re doing.
there's a very high ceiling for composing though, I just need to look at my own code from about a year ago when I first started learning clojure
my favourite was trying to reimplement the standard java/c way of doing for loops because I just didn't know about loop/recur yet
Yeah, my early code was a long ways away from what I’d write now.
yeah it's funny that. There's been a few times recently when I've been struggling to read some Clojure source code, but then the fact that I'm actually reading the source code at all is pretty telling - in earlier non-clojure days I tended just to use libraries as they were because it was much harder to figure out what was going on especially when there were a tonne of classes involved
REMINDER
re-frame-10x
allows you to do form-by-form execution tracing of event handlers. And all the trace data captured, is available in your REPL for further experimentation
https://github.com/Day8/re-frame-10x/blob/master/docs/HyperlinkedInformation/EventCodeTracing.md