Fork me on GitHub
#re-frame
<
2015-09-19
>
Pablo Fernandez19:09:28

Is there a way to check what’s the in the queue in re-frame to be handled?

Pablo Fernandez19:09:13

argh… the channel is private.

darwin19:09:15

@pupeno: hack it and access it via js namespace re_frame.router.event_chan should work

Pablo Fernandez19:09:35

darwin: actually, ^:private does nothing in ClojureScript anyway 😉

Pablo Fernandez19:09:38

I forgot about it.

Pablo Fernandez19:09:01

Now I still have the problem of wanting to stop and let the router-loop process all events… 😞

darwin19:09:38

I would recommend writing your own loop

darwin20:09:49

nevermind, I thought you want to do something special with events in the channel, pause the loop and process them on your own

darwin20:09:37

and that means I don’t understand your problem, because router will process all events

darwin20:09:50

what do you want to stop?

Pablo Fernandez20:09:07

I want to stop the current function.

Pablo Fernandez20:09:35

I have a function that just dispatched an event, I want it to stop and wait until the events have been processed.

darwin20:09:07

don’t you want to use dispatch-sync?

Pablo Fernandez20:09:45

dispatch-sync only dispatches the current event synchronously. The events dispatched by the event handler are asyncronous.

darwin20:09:28

hmm, if you want your function to wait for the results of dispatch, you will have to dispatch synchronously or use some callback mechanism

Pablo Fernandez20:09:56

What do you mean by callback mechanism?

darwin20:09:18

js has no way how to stop function and wait for some async operation, you provide a callback to that async operation, to call you back

darwin20:09:09

but it might be some other mean of calling you back, maybe you want to use another re-frame event handler to receive async “answer"

Pablo Fernandez20:09:13

I still don’t see how can I have a function run my app, gather the results, and return them 😕

darwin20:09:54

this is not possible, javascript is a single-threaded environment, you cannot stop, you have to return to the js event loop

darwin20:09:46

you can dispatch another re-frame event and do the final work in its handler

darwin20:09:30

I see what is your goal in the SO example, getting data and rendering should be decoupled, you should render once you have data in your state

Pablo Fernandez20:09:59

No, that won’t work. First, the result of render-to-string is send to the user, not the result of an arbitrary handler, if I just dispatch another handler, render-to-string will return nil. Second, even if I figure how to workaround that, I dispatch event get-foo and then dispatch event send-to-user, they’ll run in this order: get-foo, send-to-user, got-foo; where send-to-user should be handled after got-foo.

darwin20:09:53

dispatch :get-data, in :get-data handler do AJAX call, when you receive the data, dispatch :got-data which writes data into your app-db, subscribe to app-db to observe for data availability and on change dispatch :render-to-string

darwin20:09:47

render-to-string function will be called from :render-to-string handler which will be called only after/when data is available in your app-db

Pablo Fernandez20:09:32

darwin: but, what data availability should I subscribe for? there’s no single piece of data that shows that it’s done, each person writes apps in a different way.

darwin20:09:10

who does the AJAX request?

Pablo Fernandez20:09:38

The app, it’s triggered from some handlers and the result handled in a different handler.

darwin20:09:59

I’m afraid I cannot help here. If the app is a black-box which can do multiple async calls and more in reactions to them, you can be never sure that the app got all data for rendering.

darwin20:09:16

e.g. there could be a timeout, to do another AJAX fetch after few seconds

darwin20:09:46

waiting for re-frame channel to be empty is not a robust solution, I think, it will really depend on the app how it does its initial bootstrap

Pablo Fernandez20:09:19

darwin: it’s ok, server pre-rendering of single page applications can have limitations, that’s ok.

darwin20:09:02

so, you can simply do setInterval and check every few hundreds of ms if the channel is empty, and render then

Pablo Fernandez20:09:13

Indeed you can have the app doing something every second… like a js clock… and it wouldn’t make sense to wait until it’s done because that’ll never happen.

Pablo Fernandez20:09:36

darwin: there’s no way to check a channel is empty in core.async, as far as I can tell.

darwin20:09:44

it wouldn’t be a good solution anyways, the app can have some AJAX requests in flight and it wouldn’t be visible in re-frame’s channel

Pablo Fernandez20:09:21

darwin: I think during that time I can check re-frame.handlers/handling, but yes, most likely I’ll have a max time between AJAX requests and max total time defined somewhere.

darwin20:09:40

good luck, have to go