Load / Reload - return processing when complete

Load / Reload - return processing when complete

ExpresswayZExpresswayZ 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

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    Hi Steve,

    It looks like you are expecting ajax.url().load() to return a Promise, 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

  • ExpresswayZExpresswayZ Posts: 9Questions: 1Answers: 0

    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

  • ExpresswayZExpresswayZ Posts: 9Questions: 1Answers: 0
  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    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

  • ExpresswayZExpresswayZ Posts: 9Questions: 1Answers: 0

    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:

        await do_stuff_1();
        table_a.ajax.reload(reload_callback);
        await do_stuff_2();
    

    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!

  • kthorngrenkthorngren Posts: 21,351Questions: 26Answers: 4,955

    Since table_a.ajax.reload(reload_callback); is asynchronous the await do_stuff_2(); will execute immediately after. One option would be to move await do_stuff_2(); inside the reload_callback function to execute after the ajax.relaod() is complete.

    Kevin

  • ExpresswayZExpresswayZ Posts: 9Questions: 1Answers: 0

    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.

  • kthorngrenkthorngren Posts: 21,351Questions: 26Answers: 4,955

    You don't have to use ajax.reload(). You can use getJson or whatever is your preference. In the done function you can use clear() to clear the table followed by rows.add() to populate the table. This way you can use a promise and Datatables isn't in the way :smile:

    Kevin

  • ExpresswayZExpresswayZ Posts: 9Questions: 1Answers: 0

    Hi Kevin,

    Thanks for that. Can you point me to an example?

  • kthorngrenkthorngren Posts: 21,351Questions: 26Answers: 4,955
    edited March 2022

    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

  • ExpresswayZExpresswayZ Posts: 9Questions: 1Answers: 0

    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

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    Reworking:

    await do_stuff_1();
    table_a.ajax.reload(reload_callback);
    await do_stuff_2();
    

    to be the sequence you want would be:

    await do_stuff_1();
    table_a.ajax.reload(async () => {
      await do_stuff_2();
    );
    

    That would be a much better option that using setTimeouts.

    Allan

  • ExpresswayZExpresswayZ Posts: 9Questions: 1Answers: 0

    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.

  • kthorngrenkthorngren Posts: 21,351Questions: 26Answers: 4,955

    Sounds like you want to use jQuery ajax() with the async option set false. Or maybe try using this along with ajax.reload()

    $.ajaxSetup({
        async: false
    });
    

    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. The ajax.reload() is then executed synchronously.

    Kevin

  • ExpresswayZExpresswayZ Posts: 9Questions: 1Answers: 0

    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?

  • colincolin Posts: 15,240Questions: 1Answers: 2,599

    No, that would be fine. Kevin's answer should get you going,

    Colin

  • allanallan Posts: 63,542Questions: 1Answers: 10,476 Site admin

    It is actually perfectly possible to "promisify" ajax.reload():

    $.fn.dataTable.Api.register( 'reloadAsync', function (resetPaging) {
        return new Promise((resolve, reject) => {
            this.ajax.reload(
                json => resolve(json),
                resetPaging
            );
        });
    } );
    

    This is it in Kevin's example: http://live.datatables.net/nezomevu/3/edit .

    Allan

Sign In or Register to comment.