Search code examples
reactjsreact-hooksmaterial-table

React Material Table not reloading while the data is fetched


im trying to learn the JS / React, ive stuck with making the simple-shop project. Im trying to fetch the data async then load to the Material table, but idk what is wrong. The table says "no record to display", but in the console i can see the result: no desc

This is the fetch function:

  useEffect(() => {
    axios
    .get('api/OrderData/getAllOrders')
    .then(res => {
      res.data.map(async x => {
        apiData.push({
            orderId: x.orderId,
            orderGUID: x.orderGUID,
            orderName: x.orderName,
            orderDate: dateFormat(x.orderDate, "ddd mmm dd yyyy HH:MM:ss"),
            orderStatus: x.orderStatus,
            contractorId: x.contractorId,
            creatorUsername: x.creatorUsername,
            orderVendor: x.orderVendor,
            magazyn: x.magazyn,
            productId: x.productId,
            orderPayment:
            await axios
            .get("/api/Payments/getPaymentByOrderGUID?OrderGuid=" + x.orderGUID)
            .then(res => {
              if(res.status === 200)
              {
                return "Opłacone"
              }else {
                return "Nie opłacone"
              }
            })
            .catch(err => {
              console.log(err)
              return "Nie opłacone"
            }) 
      })
      })
      //do anything
      console.log(apiData)
      setTableData(apiData)
    })
    .catch(err => {
      console.log(err)
    })

    axios
    .get('api/Contractor/getAllContractors')
    .then(res => {
      res.data.map(x => {
        contractorData.push({
          contractorId: x.contractorId,
          contractorName: x.contractorName,
          contractorSurname: x.contractorSurname,
          contractorIndividualDiscount: x.contractorIndividualDiscount
      })
      })
    })
    .catch(err => {
      console.log(err)
    })
  }, [])

And the material table settings:

  <MaterialReactTable
        displayColumnDefOptions={{
          'mrt-row-actions': {
            muiTableHeadCellProps: {
              align: 'center',
            },
            size: 120,
          },
        }}
        columns={columns}
        data={tableData}
        editingMode="modal" //default
        enableColumnOrdering
        enableRowActions
        onEditingRowSave={handleSaveRowEdits}
        onEditingRowCancel={handleCancelRowEdits}
        renderRowActionMenuItems={({ row, closeMenu, table}) => [

When i delete any async / await clousules im getting same result in console but the data is showing, but the problem is that, the data is showing without one value, i mean without orderPayment, cuz it is showing as Promise, to resolve it i did the async/await but for now i cannot load it to the table...


Solution

  • I have seen your whole code but It looks like the issue might be related to the fact that setTableData(apiData) is being called outside of the async map function. Since apiData is being populated asynchronously, setTableData is likely being called before apiData has finished being populated, resulting in an empty table.

    For fixing your bug, you can use Promise.all to wait for all the promises to resolve before setting the state. Change your code above last axios getAllContractors inside useEffect Please Modify your code by my provided code:

      axios
    .get('api/OrderData/getAllOrders')
    .then(res => {
      const promises = res.data.map(async x => {
        const orderPayment = await axios
          .get("/api/Payments/getPaymentByOrderGUID?OrderGuid=" + x.orderGUID)
          .then(res => {
            if (res.status === 200) {
              return "Opłacone";
            } else {
              return "Nie opłacone";
            }
          })
          .catch(err => {
            console.log(err);
            return "Nie opłacone";
          });
        
        return {
          orderId: x.orderId,
          orderGUID: x.orderGUID,
          orderName: x.orderName,
          orderDate: dateFormat(x.orderDate, "ddd mmm dd yyyy HH:MM:ss"),
          orderStatus: x.orderStatus,
          contractorId: x.contractorId,
          creatorUsername: x.creatorUsername,
          orderVendor: x.orderVendor,
          magazyn: x.magazyn,
          productId: x.productId,
          orderPayment: orderPayment
        };
      });
      
      Promise.all(promises).then(apiData => {
        console.log(apiData);
        setTableData(apiData);
      });
    })
    .catch(err => {
      console.log(err);
    });
    

    And you know in the updated code, Promise.all is used to wait for all the promises returned by map to resolve before calling setTableData. This ensures that apiData is fully populated before trying to set the state. If you still face the error then please let me know. I'll guide you more about it.