Making fetch() Request Within preXhr.dt

Making fetch() Request Within preXhr.dt

EPonce1315EPonce1315 Posts: 2Questions: 1Answers: 0

I am trying to modify the post data sent in the table action by using the preXhr.dt trigger. My problem is that I am needing to make a fetch request to determine what data to attach.

Since fetch is async, I can't find any way to ensure the data I want gets attached as post params. I have tried a lot of things, but they have all failed.

Here is a small example for the kind of thing I am trying to do
https://live.datatables.net/eponce1315/1/edit

When trying to do this, it is hitting the end of the function before the fetch completes, and making the table action call without attaching the data I want.

I tried using await to compensate for this, but when I provide an async method to the preXhr.dt trigger, it just hits the table action before completing the method. (I also included this strategy in the code snippet, just commented out)

I want some way to ensure that the fetch call is completed and the table data is updated before the datatable makes its Xhr request.

Answers

  • kthorngrenkthorngren Posts: 21,887Questions: 26Answers: 5,057
    edited April 12

    Your test case doesn't seem to have any of the fetch code you are referring to. The Javascript fetch() has a .then() method that is called if the when successful. See this tutorial. Place the code you want to execute after the successful fetch into .then(). Maybe something like this:

      fetch(url)
        .then((response) => {
          return response.json();
        })
        .then((data) => {
          $('#example')
            .on('preXhr.dt', function (e, settings, data) {
                data.newParam= data;
            })
            .DataTable({
                ajax: 'url'
            });      
        })
    

    Kevin

  • EPonce1315EPonce1315 Posts: 2Questions: 1Answers: 0

    Hi @kthorngren

    I should have included this strategy as well in the code, but I thought it would be clear enough. I am noticing a bit of strange behavior with the link I provided, so I will instead just include the javascript as a snippet, as that is the relevant part

    I am familiar with .then() and I understand how to use it. The issue is that .then() itself is both asynchronous, and only operates after the original fetch completes, so it has the exact same issue that .fetch() does

    I cannot use what you suggested as it is defining the preXhr.dt event function only after the fetch call is run. I need to only run the fetch call when the preXhr.dt is triggered. This was the very first thing I tried, but it does not work:

    $(document).on('preXhr.dt', function (e, settings, data) {
      var url = 'someUrl';
      fetch(url).then(response => {
        response.json().then(responseData => {
          data.newData = responseData;
        })
      });
    });
    

    Again, this does not work because it exits the preXhr.dt method before the fetch request is done, and before we set data.newData

    I hope that makes this more clear

  • kthorngrenkthorngren Posts: 21,887Questions: 26Answers: 5,057
    edited April 12

    It's not totally clear to me what your code flow is and what you are doing. I haven't tested it but I think my solution might work if the data is only loaded on page load. However if you are using something like ajax.reload() to reload the data then my code snippet won't work.

    Possibly using ajax as a function will work for your requirements. I think you will be able to do the initial fetch() then use fetch() again in then() to get the table data which can be passed into the callback() function.

    Kevin

  • kthorngrenkthorngren Posts: 21,887Questions: 26Answers: 5,057
    edited April 12

    I built a simple example of using ajax as a function:
    https://live.datatables.net/socirone/52/edit

    Due to limitations with the server scripts the initial fetch() returns all the data. The second fetch() sends the first row of data from the response. This can be seen with the browser's network inspector. The callback() is used to return the second response to Datatables for display.

    Kevin

  • kthorngrenkthorngren Posts: 21,887Questions: 26Answers: 5,057

    Just for fun I decided to try my first code snippet:
    https://live.datatables.net/jukekeru/1/edit

    Had to change the data parameter used in the second then() method to something different since the preXhr also has a `data parameter. It also seems to work.

    Kevin

  • allanallan Posts: 64,269Questions: 1Answers: 10,609 Site admin

    preXhr does not look for a Promise in the returned value. The execution of the function is synchronous. The result is it cannot work with async / await.

    You can kick off an async action such as fetch in preXhr, but there is no way to tell it to wait for the asynchronous action to complete.

    I would say that making an Ajax (fetch) call to get the data to put on the Ajax request that DataTables makes is very unusual and seems wasteful. Unless there is a good reason in how your server routes are set up, I'd suggest you just synchronously assign data in preXhr as Kevin has shown and have the server resolve that (even if it needs to make an extra call to resolve the data, it will still be faster than two Ajax calls from the browser).

    Allan

Sign In or Register to comment.