Hi, can subscriptions be used inside js-event handlers, e.g. :on-click? Or should I pass their value from the component, so the handler is regenerated whenever subscription changes?
You should pass them in
ok, thanks
Hey there! I'm using the js/File.arrayBuffer()
which returns a javascript Promise, then eventually resolves with the results. When the promise resolves with results, I'd like to dispatch an API request. Any suggestions on how this should be handled in re-frame?
Just in case - it's documented here but it's still not merged in. https://github.com/day8/re-frame/pull/565
Wrap a call to dispatch
in a function, pass a function to .then
called on the promise.
Something similar to the below?
(defn make-api-request
[file]
(rf/dispatch [::make-api-request file]))
(js/File.arrayBuffer
(.then read-file))
Would you have the arrayBuffer
portion be dispatched from a separate event? The flow is user pushes button -> I need to encode the file into arrayBuffer -> then make api requestYep. Make sure to also correctly handle rejection of the promise. Or at least make sure that the standard guarantees that the promise will not be rejected by the implementation.
> Would you have the arrayBuffer portion be dispatched from a separate event? Not sure I understand the question.
If I get that right, I would do everything up to the call to dispatch
in the view. Saves quite a bit of a hussle.
My question was unclear but you figured it out -- thank you! Your suggestion makes sense
Hello. Am i able to create a re-frame event that sends a file (csv, by the way) to a browser?. I'm being able to generate the csv by event handler but don't know yet how to make it "Downloadable"
I don't understand what you mean. Who' the "client"? Is it the browser or the server? What does "send a file" mean in this case? Just being able to download it or to display it somehow?
Yes, i want to click a button and download a file in my browser
I'm using this library for that: https://github.com/eligrey/FileSaver.js/
You have to create a
element in Effect handler with attributes :href
and :download
and call click
on the element.
Something like this
(defn open-blob
[{:keys [content filename]}]
(let [attrs
(clj->js {:href (-> js/window
.-URL
(.createObjectURL content))
:download filename})
el (dom/createDom "a" attrs)]
(.click el)))
IIRC that's not a portable solution and/or has other drawbacks that the library that I linked above tries to deal with.
Sure there would be some limitations, but it could be enough solution for some cases without another dependency.
That dependency is just 170loc, including comments. :) I wouldn't count it as something worth the trade off.
👍 for fileSaver.js. I’m also using it as a re-frame effect:
(re-frame/reg-fx
::save-as!
(fn [{:keys [blob filename]}]
(filesaver/saveAs blob filename)))
When I send a GET request with re-frame-http-fx the namespace of the keys in the parameters is lost. For example,
{:http-xhrio {:method :get
:uri "<https://something.net/get-person-details>"
:params {:person/id 123}
:format (ajax/transit-request-format)
:response-format (ajax/transit-response-format)
:on-success [:get-person-success]
:on-failure [:get-person-failure]}}
The request arrives at the server as {:id 123}
instead of {:person/id 123}
. Is this intended behaviour? If so, how do you normally work around it? Do you just design your API endpoints to use non-namespaced keywords? Or use POST instead of GET?Woah, that (keyword nil "a/b")
is crazy, making the name be a/b
and the namespace nil
, I didn't know you could do that.
Needless to say, you shouldn't really rely on that. :)
I know this is late, but if you can send transit (edn) instead of json this is a non-issue. I also ran into this issue and switching to transit Just Worked
The above code has nothing to do with JSON. It's just how query parameters work. Of course you could use just a single parameter and pass it the whole transit string but it has downsides on its own.