skip to Main Content

I am having below code.

if (response.ok) {
  response.json().then((data: any) => {
    //use data
    console.log(data.value);
    let strFilesDisplayTable = "";
    strFilesDisplayTable =
      "<table border='1'> <tr> <th> Name </th> <th > Uploaded Date </th> <th > Role </th>  <th > Remove </th></tr>";
    for (var c = 0; c < data.value.length; c++) {
      var dateVal = new Date(data.value[c].TimeCreated);
      var docIdVal = data.value[c].ListItemAllFields["Role"];
      let dateTimeCreatedMod =
        dateVal.getDate().toString() +
        "/" +
        (dateVal.getMonth() + 1).toString() +
        "/" +
        dateVal.getFullYear().toString();

      strFilesDisplayTable =
        strFilesDisplayTable +
        "<tr> <td > " +
        data.value[c].Title +
        " </td> <td>" +
        data.value[c].Title +
        " </td> <td style='padding:5px;'> " +
        dateTimeCreatedMod +
        " </td> <td style='padding:5px;'> " +
        data.value[c].ListItemAllFields["Role"] +
        "  </td> <td> <button class='btnDelDoc'  onClick={this.tempFunDel(" +
        data.value[c].ListItemAllFields["ID"] +
        ")}> Delete </button> </td> </tr> ";
    }
    strFilesDisplayTable = strFilesDisplayTable + "</table>";
    document.getElementById("showFilesDiv").innerHTML = strFilesDisplayTable;
  });
}

and my function is

public tempFunDel(idVa){ alert("Id is !" +idVa); }

It renders one table for me. When I click on delete button nothing happens function "tempFunDel" is not getting called. Please suggest a workaround to call the function in the HTML string.

Thanks in advance.

2

Answers


  1. It is an anti-pattern in React to assemble HTML using strings and updating the DOM with the innerHTML property. Instead components accept properties and construct HTML elements directly using inline JSX . Run the demo below to see a minimal, reproducible example in your own browser.

    function Table({ cols = [], rows = [] }) {
      return (
        <table>
          <thead>
           <tr>
             {cols.map((c, key) =>
               <td key={key}>{c}</td>
             )}
           </tr>
          </thead>
          <tbody>
            {rows.map((r, key) =>
              <tr key={key}>
                {cols.map((c, key) =>
                  <td key={key}>{r[c]}</td>
                )}
              </tr>
            )}
          </tbody>
        </table>
      )
    }
    
    const data = [
      { name: "Alice", age: 30 },
      { name: "Bob", age: 40 },
      { name: "Charlie", age: 50 },
    ]
    
    ReactDOM.createRoot(document.querySelector("#app")).render(
      <Table cols={["name", "age"]} rows={data} />
    )
    thead { font-weight: bold; }
    tr ~ tr td { border-top: 1px solid silver; }
    <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
    <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
    <div id="app"></div>

    If the data for the Table is arriving asynchronously, a parent component can handle the request, the supplying the data to the table as props after it has loaded successfully.

    function App({ url }) {
      const [data, setData] = useState([])
      useEffect(
        () => {
          let mounted = true
          fetch(url)
            .then(res => {
              if (res.ok) return res.json()
              else throw Error("could not load data")
            })
            .then(data => mounted && setData(data))
            .catch(console.error)
          return () => { mounted = false }
        },
        [url]
      )
      return data.length == 0
        ? <Loading />
        : <Table cols={["name", "age"]} rows={data} />
    }
    

    Of course you can imagine a big headache if you have to write this for every component that needs to make a JSON request. Writing good programs means extracting behaviors so they can be easily reused –

    function useJSON(url, initialState) {
      const [state, setState] = useState(initialState)
      useEffect(
        () => {
          let mounted = true
          fetch(url)
            .then(res => {
              if (res.ok) return res.json()
              else throw Error("could not load data")
            })
            .then(data => mounted && setData(data))
            .catch(console.error)
          return () => { mounted = false }
        },
        [url]
      )
    }
    

    Now writing App is a breeze –

    import { useJSON } from "./hooks.jsx"
    
    function App({ url }) {
      const data = useJSON(url, [])
      return data.length == 0
        ? <Loading />
        : <Table cols={["name", "age"]} rows={data} />
    }
    
    Login or Signup to reply.
  2. You’re calling the following in your structure:

    onClick={this.tempFunDel("+data.value[c].ListItemAllFields['ID']+")}
    

    To call a function with parameters, according to the official documentation, you have to do the following:

    onClick={() => this.tempFunDel("+data.value[c].ListItemAllFields['ID']+")}
    

    Link to the ReactJS documentation: https://reactjs.org/docs/handling-events.html#passing-arguments-to-event-handlers

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search