0

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);
Tan
  • 1,433
  • 5
  • 27
  • 47
  • Noticed that you are not using the data that I'm dynamically generating, could you elaborate please on this? – Tan May 02 '22 at 16:50
  • Basically I want to use this data and have all the functionality work:`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 }; }` – Tan May 02 '22 at 16:56
  • [https://codesandbox.io/s/modest-bird-7tlvhf](https://codesandbox.io/s/modest-bird-7tlvhf) – jsN00b May 02 '22 at 17:06
  • above sandbox seems to be using the data from the json file which I'm not looking for. I'm looking to display data that I am generating as explained in my previous comment. Please let me know if I can answer any questions. – Tan May 02 '22 at 17:12
  • In my scenario, I won't know in advance how many rows I have to display. Hence I was planning on using seperate `data` variable. How can that be achieved if we use `products2` ? – Tan May 02 '22 at 17:14
  • _I won't know in advance how many rows I have to display_ ---> In [https://codesandbox.io/s/modest-bird-7tlvhf](https://codesandbox.io/s/modest-bird-7tlvhf) at line 47: `[...Array(15).keys()].map((i) => ({`. Right now, the number is set to 15. You can change it exactly how you would do with the `for` loop (where you have `i < 4`). – jsN00b May 02 '22 at 17:17
  • Please help me understand this. The line # 45 which is `productService.getProductsSmall().then((data) =>` is not making use of the filr `data/products-small.json` ? – Tan May 02 '22 at 17:24
  • 1
    Yeah, I didn't want to make use of the static file. What it's currently doing is what I was looking for. Thanks for your response though and time. Appreciated! – Tan May 02 '22 at 17:30
  • If you are planning to delete above comments with the modified codesandbox answers, if possible please respond to my question as an answer. I will be happy to accept. – Tan May 02 '22 at 18:34
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/244409/discussion-between-jsn00b-and-tan). – jsN00b May 02 '22 at 18:35

0 Answers0