gregnb / mui-datatables

Datatables for React using Material-UI
MIT License
2.71k stars 932 forks source link

Clicking on rows per page dropdown results in infinite "Uncaught RangeError: Maximum call stack size exceeded." #1546

Open waqar-ali-intagleo opened 4 years ago

waqar-ali-intagleo commented 4 years ago

render() { const { type } = this.props; const ocrType = mixConstants.visualAssetType.OCR;

const { assets } = this.props;

const { disableDeleteButton } = this.props;

var windowHeight = $(window).height() - 330;

const minMaxHeightTheme = createMuiTheme({
  overrides: {
    MUIDataTable: {
      responsiveScroll: {
        maxHeight: windowHeight,
        minHeight: windowHeight,
      },
    },
  },
});

const logoOrTextView = {
  name: type === ocrType ? "Image/Text" : "Logo",
  options: {
    filter: false,
    customBodyRender: (value, tableMeta, updateValue) => {
      const asset = assets[tableMeta.rowIndex];
      const logo = asset.logo;
      const calloutText = asset.calloutText;
      return logo ? (
        <img className="assets-image" src={logo} alt="logo" />
      ) : calloutText ? (
        calloutText
      ) : (
        ""
      );
    },
  },
};

const imageOrTextName = {
  name: "Name",
  options: {
    filter: false,
    customBodyRender: (value, tableMeta, updateValue) => {
      const asset = assets[tableMeta.rowIndex];
      const imageOrTextName = asset.imageOrTextName;
      return imageOrTextName;
    },
  },
};

const isDefaultImage = {
  name: "Default",
  options: {
    filter: true,
    filterType: "checkbox",
    customBodyRender: (value, tableMeta, updateValue) => {
      const asset = assets[tableMeta.rowIndex];
      const isDefault = asset.isDefault;
      return (
        <label className="custom-checkbox">
          <input
            type="checkbox"
            value="id"
            checked={isDefault}
            onClick={() => this.handleDefaultImageCheck(asset)}
          />
          <span className="checkmark"></span>
        </label>
      );
    },
  },
};

const deleteAction = {
  name: "Delete",
  options: {
    filter: false,
    customBodyRender: (value, tableMeta, updateValue) => {
      const asset = assets[tableMeta.rowIndex];
      return (
        <button
          disabled={!disableDeleteButton}
          className="remove-row"
          onClick={() => this.removeButtonClicked(asset)}
        >
          X
        </button>
      );
    },
  },
};

const modelTrained = {
  name: "Model Trained",
  options: {
    filter: false,
    customBodyRender: (value, tableMeta, updateValue) => {
      const asset = assets[tableMeta.rowIndex];
      const isModelTrained = asset.isModelTrained;
      return (
        <select
          className="model-select"
          value={isModelTrained ? "Yes" : "No"}
          onChange={() => this.handleIsModelTrainedOption(asset)}
        >
          <option> Yes </option>
          <option> No </option>
        </select>
      );
    },
  },
};

let columns = [
  logoOrTextView,
  imageOrTextName,
  { name: "Upload Date" },
  modelTrained,
  isDefaultImage,
  deleteAction,
];

let mappedAssetsData = [];

if (assets && assets.length > 0) {
  mappedAssetsData = assets.map((asset) => {
    const uploadedOn = asset.uploadedOn;
    const formattedUploadedOn = uploadedOn
      ? moment(uploadedOn).format("l")
      : "";
    return ["", "", formattedUploadedOn, "", "", ""];
  });
}

const options = this.props.options
  ? this.props.options
  : {
      searchOpen: false,
      searchPlaceholder: "Search assets",
      filterType: "dropdown",
      search: false,
      sort: false,
      selectableRows: "none",
      rowsPerPage: 5,
      responsive: "scrollMaxHeight", //scrollMaxHeight OR scrollFullHeight OR stacked
      rowsPerPageOptions: [5, 10, 15, 20],
      pagination: mappedAssetsData.length > 5 ? true : false,
      print: false,
      download: false,
      viewColumns: false,
      filter: false,
      searchText: this.searchedText !== "" ? this.searchedText : "",

      textLabels: {
        body: {
          noMatch: "No assets found",
        },
        pagination: {
          rowsPerPage: "Assets per page:",
        },
      },
    };

return (
  <div className="company-dashboard-brands-table ">
    <MuiThemeProvider theme={minMaxHeightTheme}>
      <MUIDataTable
        title=""
        data={mappedAssetsData}
        columns={columns}
        options={options}
      />
    </MuiThemeProvider>
  </div>
);

}

Expected Behavior

It should show the dropdown with selectable rows per page options.

Current Behavior

App gets stuck in infinite "Uncaught RangeError: Maximum call stack size exceeded."

Steps to Reproduce (for bugs)

just click on the rows per page dropdown

My Environment

Tech Version
Material-UI 4.9.7
MUI-datatables 2.14.0
React 16.13.0
browser Chrome
patorjk commented 4 years ago

Looks like you're using an old version of the library. The current version is 3.5.

waqar-ali-intagleo commented 4 years ago

@patorjk I am using the same data table in different places and they work fine but this code is generating the error. I compared the code but unable to find where I am doing wrong here.

wdh2100 commented 4 years ago

@waqar-ali-intagleo

I don't think it's an rowsPerPage option problem...

codesandbox(MUI-datatables | 2.14.0) : https://codesandbox.io/s/muidatatables-custom-toolbar-forked-ohem7?file=/index.js

I think I need the input data...

Please provide codesandbox.

waqar-ali-intagleo commented 4 years ago

I have found the solution the issue was due to the popup dialog. I am adding the mui-datatable in the popup dialog. The solution is add the prop disableEnforceFocus to the Dialog component.

https://stackoverflow.com/questions/54133326/material-ui-uncaught-rangeerror-maximum-call-stack-size-exceeded

wdh2100 commented 4 years ago
const modelTrained = {
  name: "Model Trained",
  options: {
    filter: false,
    customBodyRender: (value, tableMeta, updateValue) => {
      const asset = assets[tableMeta.rowIndex];
      const isModelTrained = asset.isModelTrained;
      return (
        <select
          className="model-select"
          value={isModelTrained ? "Yes" : "No"}
          onChange={() => this.handleIsModelTrainedOption(asset)}
        >
          <option> Yes </option>
          <option> No </option>
        </select>
      );
    }
  },

@waqar-ali-intagleo

Is the Maximum call stack size exceeded here ❓

So, did Maximum call stack size exceeded solve❓