Load / Reload - return processing when complete
Load / Reload - return processing when complete
ExpresswayZ
Posts: 9Questions: 1Answers: 0
Hi Guys,
I'm looking for a code example.
I have a dataTable populated from a relational query via an ajax call. Parameters to this call are in the URL and these can change depending on user input. To load the table with new data, from an async function, I call:
await historic_load_datatable.ajax.url(historic_load_url).load();
However, this always immediately returns while the dataTable fetches the data and refreshes.
Can anyone point me to an example where this call pauses until complete?
Cheers
Steve
Answers
Hi Steve,
It looks like you are expecting
ajax.url().load()
to return aPromise
, which it doesn't. Rather, if you look at the documentation for it it has a callback as the first parameter which you would use to wait until the load has completed for whatever the next action is.Allan
Not sure how to implement that - I was looking for an example.
To clarify, I've created a JSBin - link below.
If you click the [Reload] button, the console messages show the call to do_stuff_2 starts before the reload has completed. How would I change this so that processing pauses until the reload has finished before continuing. I've created a callback function on the reload and that certainly waits for the reload to finish, but it doesn't hold up the main process.
Any suggestions appreciated.
http://live.datatables.net/bayisodo/6/edit?html,css,js,console,output
JS Bin edited for clarity: http://live.datatables.net/bayisodo/7/edit?html,css,js,console,output
I've updated your bin to fake a slow response from the server: http://live.datatables.net/bayisodo/8/edit .
The problem was that before, because of the timings, everything happens too fast. When it's slowed down, you'll see the
reload_callback
is the last function being executed, as expected,Colin
Hi Colin,
Thanks for the reply but I don't think I made myself clear...
The order of the function calls in the on-click event handler is:
but the order of execution (by way of the console log) is:
"Button clicked"
"do_stuff_1 call"
"do_stuff_1 start"
"do_stuff_1 end"
"do_stuff_1 back"
"do_stuff_2 call"
"do_stuff_2 start"
"do_stuff_2 end"
"do_stuff_2 back"
"reload_callback start"
"reload_callback end"
The order I am looking for is...
"Button clicked"
"do_stuff_1 call"
"do_stuff_1 start"
"do_stuff_1 end"
"do_stuff_1 back"
"reload_callback start"
"reload_callback end"
"do_stuff_2 call"
"do_stuff_2 start"
"do_stuff_2 end"
"do_stuff_2 back"
...because do_stuff_2 has a dependency on the reload.
Is there a way of the javascript waiting for the reload to complete before starting do_stuff_2?
Of course, I could cludge the hell out of this - define and unset a flag, get the reload to set the flag, and only start do_stuff_2 when the flag flips - but there must be a better way than that!
Since
table_a.ajax.reload(reload_callback);
is asynchronous theawait do_stuff_2();
will execute immediately after. One option would be to moveawait do_stuff_2();
inside thereload_callback
function to execute after theajax.relaod()
is complete.Kevin
Hi Keven,
Yeah, I think that's what I'm asking; how to make reload synchronous. It's a shame that it doesn't return a Promise.
I don't really want to nest the code in the way you suggest. The actual application is more complex that the example I used and things are going to get very messy very quickly.
I will probably end up using a control variable to overlay synchronicity on the call. It'll be cludgy but it should work. I'll put up my solution later, see if anyone can suggest improvements.
You don't have to use
ajax.reload()
. You can use getJson or whatever is your preference. In the done function you can useclear()
to clear the table followed byrows.add()
to populate the table. This way you can use a promise and Datatables isn't in the wayKevin
Hi Kevin,
Thanks for that. Can you point me to an example?
Here is an example of using getJSON() and the Datatables APIs:
http://live.datatables.net/nezomevu/1/edit
If you need a tutorial for using promises with getJSON, which is outside the scope of this forum, see this article. Or maybe Stack Overflow will have techniques you can use to meet your needs.
Kevin
Hi Guys,
Well, I've come up with a solution - and opinions would be welcome. I'm sure there's gotchas in there.
I've put a div on the web page to act as an universal global (js globals & callbacks are not straight forward), and update / read this to communicate to the main process whether it should wait or continue:
I know this approach not pretty but it appears to work with this fairly basic use case:
fyi, the // noprotect in the wait_for_continue function stops the js engine breaking out of the loop if it goes on too long (> 500ms, I think). For safety, I think an emergency stop should be put into that loop (probably a time out) to shut it down if it runs too long. That needs to be tuned to the expected response of the database / dataTables.
Anyway, please feel free to comment...
http://live.datatables.net/bayisodo/40/edit?html,js,console,output
Reworking:
to be the sequence you want would be:
That would be a much better option that using setTimeouts.
Allan
Thanks for that Allan but I covered this case earlier. It would be fine for the simple case presented here but my live code has a lot more going on - not least a reload call inside a loop. That would get very messy very quickly. I really need a solution where the reload call suspends all current processing until it is complete.
Sounds like you want to use jQuery ajax() with the async option set false. Or maybe try using this along with
ajax.reload()
You can toggle the async setting as needed. See this example:
http://live.datatables.net/nezomevu/2/edit
The datatable is initialized asynchronously and sets the above in
initComplete
. Theajax.reload()
is then executed synchronously.Kevin
Hi Kevin,
Do you think there is a problem with my solution - where I use a DOM div as a controller? My tests so far suggests that it does what I need it to. Is that a cludge too far?
No, that would be fine. Kevin's answer should get you going,
Colin
It is actually perfectly possible to "promisify"
ajax.reload()
:This is it in Kevin's example: http://live.datatables.net/nezomevu/3/edit .
Allan