'dynamic data is not iterable

Please refer to the sandbox link here

I'm using my own dynamically generated data and hence using the following in my code:

const onRowEditComplete1 = (e) => {
let _dynamicData = [...dynamicData]; 
let { newData, index } = e;
_dynamicData[index] = newData;
setDynamicData(_dynamicData); };

And

<DataTable
//value={products2} 
 value={data} 
 editMode="row" 
 dataKey="id" 
 onRowEditComplete={onRowEditComplete1} 
 responsiveLayout="scroll">

If I try to change the status from In stock to Low stock, It keeps on throwing TypeError dynamicData is not iterable as you can see in the sandbox above.

However, when I change it to the following to use the data from the primereact sandbox example:

const onRowEditComplete1 = (e) => {
let _products2 = [...products2]; let { newData, index } = e;
_products2[index] = newData;
setProducts2(_products2);
};
<DataTable
 value={products2}
 editMode="row"
 dataKey="id"
 onRowEditComplete={onRowEditComplete1}
 responsiveLayout="scroll"
 >

It doesn't throw any error after editing a row and saving the changes. How to fix the error in case of the data that I'm using there so that it starts saving properly?

My complete code if needed for reference:

export const FileUploadDemo = () => {
  const [totalSize, setTotalSize] = useState(0);

  const toast = useRef(null);
  const fileUploadRef = useRef(null);
  //start:Row Editing Work
  const [products2, setProducts2] = useState(null);
  const [dynamicData, setDynamicData] = useState(null);

  const statuses = [
    { label: "In Stock", value: "INSTOCK" },
    { label: "Low Stock", value: "LOWSTOCK" },
    { label: "Out of Stock", value: "OUTOFSTOCK" }
  ];

  const dataTableFuncMap = {
    products2: setProducts2
    //dynamicData: setDynamicData
  };

  const productService = new ProductService();
  useEffect(() => {
    fetchProductData("products2");
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  const fetchProductData = (productStateKey) => {
    productService
      .getProductsSmall()
      .then((data) => dataTableFuncMap[`${productStateKey}`](data));
  };
  const getStatusLabel = (status) => {
    switch (status) {
      case "INSTOCK":
        return "In Stock";

      case "LOWSTOCK":
        return "Low Stock";

      case "OUTOFSTOCK":
        return "Out of Stock";

      default:
        return "NA";
    }
  };

//   const onRowEditComplete1 = (e) => {
//     // console.log("Testing e");
//     // console.log(e);
//     let _products2 = [...products2];
//     let { newData, index } = e;

//     _products2[index] = newData;

//     setProducts2(_products2);
//   };
    const onRowEditComplete1 = (e) => {
        console.log("Testing e")
        console.log(e);
      let _dynamicData = [...dynamicData];
      let { newData, index } = e;

      _dynamicData[index] = newData;

      setDynamicData(_dynamicData);
    };

  const textEditor = (options) => {
    return (
      <InputText
        type="text"
        value={options.value}
        onChange={(e) => options.editorCallback(e.target.value)}
      />
    );
  };
  const statusEditor = (options) => {
    return (
      <Dropdown
        value={options.value}
        options={statuses}
        optionLabel="label"
        optionValue="value"
        onChange={(e) => options.editorCallback(e.value)}
        placeholder="Select a Status"
        itemTemplate={(option) => {
          return (
            <span
              className={`product-badge status-${option.value.toLowerCase()}`}
            >
              {option.label}
            </span>
          );
        }}
      />
    );
  };

  const priceEditor = (options) => {
    return (
      <InputNumber
        value={options.value}
        onValueChange={(e) => options.editorCallback(e.value)}
        mode="currency"
        currency="USD"
        locale="en-US"
      />
    );
  };

  const statusBodyTemplate = (rowData) => {
    return getStatusLabel(rowData.inventoryStatus);
  };

  const priceBodyTemplate = (rowData) => {
    return new Intl.NumberFormat("en-US", {
      style: "currency",
      currency: "USD"
    }).format(rowData.price);
  };

  //END:Row Editing Work

  const onUpload = (e) => {
    toast.current.show({
      severity: "info",
      summary: "Success",
      detail: "File Uploaded"
    });
    console.log("File Upload event e");
    console.log(e);
    setTotalSize(e.length);
  };

  let data = [];
  for (let i = 0; i < 4; i++) {
    data[i] = {
      id: i + 1,
      code: "cm230f032" + i + 1,
      name: "Gaming Set" + i + 1,
      description: "Product Description" + i + 1,
      image: "gaming-set.jpg" + i + 1,
      price: i + 2,
      category: "Electronics" + i + 1,
      quantity: i + 3,
      inventoryStatus: "INSTOCK",
      rating: i + 1
    };
  }

  console.log("Printing Data");
  console.log(data)
//   var result = Object.keys(data).map((key) => [Number(key), data[key]]);

// console.log(result);

  return (
    <div>
      <Toast ref={toast}></Toast>

      <Tooltip target=".custom-choose-btn" content="Choose" position="bottom" />
      <Tooltip target=".custom-upload-btn" content="Upload" position="bottom" />
      <Tooltip target=".custom-cancel-btn" content="Clear" position="bottom" />

      <div className="card">
        <h5>Advanced</h5>
        <FileUpload
          name="demo[]"
          url="https://primefaces.org/primereact/showcase/upload.php"
          //onUpload={onUpload}
          customUpload
          uploadHandler={onUpload}
          multiple
          accept="image/*"
          maxFileSize={1000000}
          emptyTemplate={
            <p className="m-0">Drag and drop files to here to upload.</p>
          }
        />
      </div>

      <div className="datatable-editing-demo">
        <Toast ref={toast} />

        <div className="card p-fluid">
          <h5>Row Editing</h5>
          <DataTable
            //value={products2}
            value={data}
            editMode="row"
            dataKey="id"
            onRowEditComplete={onRowEditComplete1}
            responsiveLayout="scroll"
          >
            <Column
              field="code"
              header="Code"
              editor={(options) => textEditor(options)}
              style={{ width: "20%" }}
            ></Column>
            <Column
              field="name"
              header="Name"
              editor={(options) => textEditor(options)}
              style={{ width: "20%" }}
            ></Column>
            <Column
              field="inventoryStatus"
              header="Status"
              body={statusBodyTemplate}
              editor={(options) => statusEditor(options)}
              style={{ width: "20%" }}
            ></Column>
            <Column
              field="price"
              header="Price"
              body={priceBodyTemplate}
              editor={(options) => priceEditor(options)}
              style={{ width: "20%" }}
            ></Column>
            <Column
              rowEditor
              headerStyle={{ width: "10%", minWidth: "8rem" }}
              bodyStyle={{ textAlign: "center" }}
            ></Column>
          </DataTable>
        </div>
      </div>
    </div>
  );
};

const rootElement = document.getElementById("root");
ReactDOM.render(<FileUploadDemo />, rootElement);


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source