BranOIE
BranOIE

Reputation: 430

Wait for map function to finish but append to variable

Currently my code is like so:

const exportPdf = async () => {
      let crops = <?=json_encode($crops)?>;
      let pestTables;

      let fillPestTables = crops.map(crop, index) => {
        let tableBody = await getTableBody(crop, index);
        $(pestTables).append(tableBody);
      });

      console.log(pestTables);

    }

The function you see, gets called when a button is clicked. As of now, the console.log(pestTables) gets called straight away. The function being called in the map works fine as if I do a console.log in the map function, it logs what I want. Here is the function in the map:

const getTableBody = async (crop, index) => {
      return new Promise((resolve, reject) => {
        table = $(`#pests_js_table${index}`).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
          ],
          "initComplete": function() {
            resolve($(`#pests_js_table${index}`).html());
            table.destroy();
          }
        });
      })
    }

I am very new to using promises so if I have messed something up I apologize. Anyone that can guide me in the right direction or explain what needs to happen here?

Thanks

Upvotes: 0

Views: 56

Answers (3)

Rashed Rahat
Rashed Rahat

Reputation: 2495

Here is the solution:

const exportPdf = async () => {
      let crops = <?=json_encode($crops)?>;
      let pestTables;

      let fillPestTables = crops.map(crop, index) => {
        await getTableBody(crop, index).then(res => $(pestTables).append(res););
      });

      console.log(pestTables);

    }

Upvotes: 0

Rifat Bin Reza
Rifat Bin Reza

Reputation: 2781

You need to use async function for the map to finish

let fillPestTables = crops.map(async function (crop, index) => {
  let tableBody = await getTableBody(crop, index);
  $(pestTables).append(tableBody);
});

Upvotes: 1

mousetail
mousetail

Reputation: 8010

To generate a awaitable from a list of promises use Promise.all():

const fillPestTables = await Promise.all(
    crops.map(
        async (crop, index)=>{/*...*/}
    )
)

This executes all the promises at the same time and resumes when all of them have been completed, returning a list of the responses.

Upvotes: 0

Related Questions