-2

I have a function that involves fetching data via ajax and making a table and returning said table. I also have a function that gets triggered when a button is clicked. I have names this function with async and hoped that when i called the function to get the table, it would wait for it to finish (I have used await) then the rest of the code would follow. But instead the console logs the table with no data in it (because it needs time for the data to be fetched), instead console logs the empty table right away.

The trigger function

const exportPdf = async () => { //Called from a button 
      let tableBody = await getTableBody('v7xn82Ff3XQFYwCl');
      console.log(tableBody);
    }

The function that returns the table

const getTableBody = async (crop) => {
      table = $('#pests_js_table').DataTable({
        "pageLength": 50,
        "processing": true,
        "ajax": {
          "url": '/assets/ajax/table_ajax_handler.php',
          "type": "POST",
          "data": {
            action: "getPestsForTable"
          }
        },
        "rowsGroup": [

        ],
        "columns": [{
            "data": "crop"
          },
          {
            "data": "pests"
          },
          {
            "data": "chemical"
          },
          {
            "data": "product"
          },
          {
            "data": "rate"
          },
          {
            "data": "max_no"
          },
          {
            "data": "hi"
          },
          {
            "data": "mrl"
          },
          {
            "data": "pcs_no"
          },
          {
            "data": "supplier"
          },
          {
            "data": "use_by_date"
          }
        ],
        "columnDefs": [{
            "targets": [0],
            "visible": false,
            "searchable": true
          },
          {
            "targets": [1],
            "visible": true,
            "searchable": true
          }
        ],
        "order": [
          [2, "asc"]
        ],
        "rowsGroup": [
          1, 2, 4, 5, 6, 7, 9
        ]
      });

      let tableBody = $('#pests_js_table').html();
      table.destroy();
      return tableBody;
    }
BranOIE
  • 400
  • 4
  • 19
  • 2
    `getTableBody` isn't waiting for `DataTable` to finish its ajax stuff… but why should it? You aren't awaiting a promise there. – Quentin Mar 18 '21 at 16:32
  • 1
    I don’t see any `await` in `getTableBody` that’s why. – hackape Mar 18 '21 at 16:33
  • Look in the `DataTable` API for how it tells you it's finished its work (it probably provides a callback, though if it's been updated recently it might provide a promise). If it provides a callback, see [this question's answers](https://stackoverflow.com/questions/22519784/how-do-i-convert-an-existing-callback-api-to-promises) for how to wrap it with a promise you can return so `await` waits for it. – T.J. Crowder Mar 18 '21 at 16:35

1 Answers1

0

Your getTableBody function returns a string immediately since it's not awaiting anything. So if the result of calling DataTable isn't awaitable you need to return a Promise and call resolve when you actually have a value to return, like:

const getTableBody = async crop => {
  return new Promise((resolve, reject) => {
    const table = $('#pests_js_table').DataTable({
      ajax: {
        success: resp => {
          resolve($('#pests_js_table').html()) // <-- call resolve when ready
          table.destroy()
        },
        ... // etc.
      },
      ... // etc.
    })
  })
}
Brandon Hill
  • 1,782
  • 14
  • 12
  • I have tried this and I am still getting the same output as before. Is there a change I should make when calling `getTableBody` ? – BranOIE Mar 18 '21 at 16:48