re-frame

https://github.com/Day8/re-frame/blob/master/docs/README.md https://github.com/Day8/re-frame/blob/master/docs/External-Resources.md
2020-12-04T01:29:19.409400Z

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?

isak 2020-12-04T01:47:00.409600Z

You should pass them in

2020-12-04T02:16:28.409800Z

ok, thanks

Alex 2020-12-04T05:08:09.411300Z

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?

p-himik 2020-12-04T05:19:44.411400Z

Just in case - it's documented here but it's still not merged in. https://github.com/day8/re-frame/pull/565

p-himik 2020-12-04T05:20:40.411700Z

Wrap a call to dispatch in a function, pass a function to .then called on the promise.

Alex 2020-12-04T05:28:36.411900Z

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 request

p-himik 2020-12-04T05:30:58.412100Z

Yep. 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.

p-himik 2020-12-04T05:31:16.412300Z

> Would you have the arrayBuffer portion be dispatched from a separate event? Not sure I understand the question.

p-himik 2020-12-04T05:31:54.412500Z

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.

Alex 2020-12-04T05:33:10.412700Z

My question was unclear but you figured it out -- thank you! Your suggestion makes sense

1👍
Ramon Rios 2020-12-04T09:08:55.415300Z

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"

p-himik 2020-12-04T09:14:12.415500Z

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?

Ramon Rios 2020-12-04T09:14:53.415700Z

Yes, i want to click a button and download a file in my browser

p-himik 2020-12-04T09:15:02.415900Z

I'm using this library for that: https://github.com/eligrey/FileSaver.js/

lukas.rychtecky 2020-12-04T09:37:26.416200Z

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)))

p-himik 2020-12-04T09:44:46.416400Z

IIRC that's not a portable solution and/or has other drawbacks that the library that I linked above tries to deal with.

lukas.rychtecky 2020-12-04T10:33:16.416600Z

Sure there would be some limitations, but it could be enough solution for some cases without another dependency.

p-himik 2020-12-04T10:36:06.416800Z

That dependency is just 170loc, including comments. :) I wouldn't count it as something worth the trade off.

1💯
valtteri 2020-12-04T19:44:05.417100Z

👍 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)))

tobias 2020-12-04T22:45:11.418800Z

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?

tobias 2020-12-05T11:50:26.419800Z

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.

p-himik 2020-12-05T11:52:17.420Z

Needless to say, you shouldn't really rely on that. :)

2020-12-11T05:39:36.430700Z

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

p-himik 2020-12-11T07:33:18.430900Z

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.