Fork me on GitHub
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.


@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… 😞


I would recommend writing your own loop


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


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


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.


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.


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?


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


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 😕


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


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


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.


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


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.


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.


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.


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


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.


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.


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.


good luck, have to go