Fork me on GitHub
#re-frame
<
2016-03-10
>
dragoncube00:03:40

that is the best way in re-frame to to fetch data asynchronously (HTTP GET) from multiple resources, wait until everything fetched, transform all responses into one and then render it?

dd02:03:25

@dragoncube: core.async

dd02:03:20

is there a way to hook into and listen to re-frame’s router in order to test if the correct dispatches were fired off in the following function:

danielcompton02:03:41

@dd what would you be testing?

dd02:03:58

that the router correctly dispatches :A :B :C

dd02:03:04

as side effects

dd02:03:14

and not some other 😄

danielcompton02:03:17

it’s just a function call? If function calls are failing then you’ve got big problems on your hands simple_smile

dd02:03:23

not smiley face

dd02:03:30

but “:D"

dd02:03:52

There are some cases where I have dispatch functions that will dispatch other dispatch functions depending on the input and logic

dd02:03:35

Just curious if you guys knew if there was a way to test if the router correctly calls the right functions

dd02:03:12

@danielcompton: btw thanks for the prompt response!

dd02:03:04

this function will go into the register-handler fun

dd02:03:08

function*

dragoncube02:03:03

@dd if you use core.async from handlers you would prevent any events processed by re-frame until all resources are fetched and processed

dd02:03:22

what I did was render a loading screen

dragoncube02:03:57

@danielcompton @mikethompson is there any other approaches for this? (https://clojurians.slack.com/archives/re-frame/p1457569360000902)

dd02:03:07

call another fn that did the multi requests and then when it was finished dispatch another function with the payload

danielcompton02:03:57

@dragoncube: nothing will be prevented from being processed, you will be running your core.async code in a go block, and the handler will have exited (remember to return a value for db!)

dragoncube02:03:54

@danielcompton: and dispatch another event with result at the end of go block?

danielcompton02:03:51

So we have something like

(register-handler
  :my-handler
  base-middleware
  (fn
    [db [event-k]]
    (go (let [v1 (returns a channel)
              v2 (returns a channel)]
          (do something with both channels)
          (dispatch [:result value])))
    db))

mikethompson03:03:02

@dragoncube: > if you use core.async from handlers you would prevent any events processed by re-frame until all resources are fetched and processed No, it won't block. The event handler will return (returning an unchanged db). Other events can then be processed, as necessary. At some point in the future that go block will itself dispatch the combined result of both HTTP requests, and that will be appropriately handled. (I'm looking above at Daniel's code as I write this)

nidu04:03:37

@danielcompton: Currently APIs for simple/dynamic subscriptions are different as I understand - you have to pass dynamic sub arguments separately. Didn't you think to unify API somehow so caller could decide whether the subscription is dynamic or not? I guess it has some implementation difficulties.

danielcompton05:03:17

@nidu: there’s a few reasons: 1. Implementation difficulties - It's probably doable, but would be more complicated 2. Performance - There are two reactions created for every dynamic subscription, and one for a normal subscription. It’s not a big deal, but nice to avoid if you don’t need it 3. Error handling - If we unified the v and dynv in subscriptions, then we wouldn’t be able to check if the user accidentally passed a static value when they meant to pass a dynamic value 4. API design - I think it should be immediately obvious to a reader when you’re using a dynamic subscription vs. a standard subscription. Unifying them would stop this. I guess I see dynamic subscriptions as the icing on a cake of standard subscriptions. They’re good to have, and you need them sometimes, but you don’t want a cake that is all icing If you did want to combine the two, you could register a subscription function with two arities to allow you to call subscribe with both static and dynamic values.

nidu05:03:28

@danielcompton: good points, thanks for explanation

mccraigmccraig07:03:26

@dragoncube i use promesa with cats alet (aka applicative-do) for the async fetch graph problem. it's awesome

pepe08:03:40

@mccraigmccraig: can you please elaborate a little? I am just thinking about something better, that I have now (cascade of dispatches)

mccraigmccraig09:03:44

@pepe: have a look at http://funcool.github.io/promesa/latest/#advanced-chaining ... alet will work out the dependencies between intermediate results and do operations in "parallel" where possible - the disadvantage is that you don't get to see the intermediate results in your app-db

pepe10:03:39

@mccraigmccraig: thank you, I will

dragoncube16:03:44

@mccraigmccraig: promises doesn’t sound like FRP which is re-frame is for so mixing these two seems strange

mccraigmccraig16:03:12

@dragoncube: you are probably already going to use something like a promise or a promise-channel to get a response from an API... composing those is not entirely unnatural

mccraigmccraig16:03:17

i agree that it's kinda opaque, and that it would be nice to have some principled method of resolving the dependency graph in the app-db

mccraigmccraig16:03:04

i've only got one place in my app where i use this technique, which is during initialisation where if i don't get a few basic pieces of info from the api everything breaks - the alet technique saved me tearing out what little of my hair remains over specifying and managing the state-machine manually simple_smile

dragoncube16:03:50

@mccraigmccraig: for me it is all across the whole app, in different kinds and variations, so I want to have cleaner approach

dragoncube16:03:07

@mccraigmccraig: it is actually good you mentioned composability, it is one of the problems with cascade of dispatches - very bad composability and reusability. @danielcompton @mikethompson any thoughts on this? BTW, is it right observation that with re-frame it is all clean and clear while you writing custom handlers to to the things but once you start generalize things it starts looking like imperative style with global vars due to events like [:set-value :db-value-path actual-value]?

dragoncube16:03:37

@nidu: yes, I read this wiki, it looks more or less like what I need but not sure if there are any caveats of doing it this way

danielcompton18:03:42

Not quite sure what the question is @dragoncube

mikethompson19:03:45

My guess is that Reuters used re-frame to build this: http://open.mediaexpress.reuters.com/all

nidu19:03:43

Well re-frame can be found in sources

nidu19:03:11

Strings like "re-frame: expected a vector event, but got: "

nidu19:03:36

Sounds cool anyway!

mangr3n19:03:47

so, don’t do event dispatches in a ubiquitous enrich middleware….

mangr3n20:03:27

all operations on the db should be available as pure functions AND then if necessary registered as handlers…