0

I am new to typescript and I am trying to build a CRUD app that builds out a table with buttons that allow a user to click on the button to populate the form for updating of that item. Right now it works with typing the ID of the list item in a box and clicking a button but I felt adding a button tied to an ID already would save them a step. I have two methods one that grabs the items in the list and builds the table and then one that grabs the specific item.

Normally in Vanilla JS I would just add the function call with the argument in the onclick attribute in my JS and that would work. My code is below. The first is the read all items and the second is the one that grabs the specific ID. that I would like to call with the button onclick. I did get it to spit out the HTML with the readAllItems(ID) in the HTML but when clicked it errored saying readListItem was undefined even if I put it before readAllItems. Any help is appreciated

EDIT: I have updated to code to have the call to the readListItem function and removed a line that was not needed. I am just trying to bind the buttons that get created in the forEach in the table to run the readListItem function based on the item ID.

private readAllItems() : void{
    
    this._getListItems().then(listItems => {
      let html: string = '<table border=1 width=100% style="border-collapse: collapse;">';
      html += '<th>ID Edit</th><th>Title</th> <th>Vendor</th><th>Description</th><th>Name</th><th>Version</th>';

    listItems.forEach(listItem => {
      html += `<tr>     
      <td><button class="editButton" onclick=${this.readListItem(listItem.Id)} data-item-id="${listItem.Id}">Edit</button></td>       
      <td>${listItem.Title}</td>
      <td>${listItem.SoftwareVendor}</td>
      <td>${listItem.SoftwareDescription}</td>
      <td>${listItem.SoftwareName}</td>
      <td>${listItem.SoftwareVersion}</td>      
      </tr>`;
    });
    html += '</table>';
    const listContainer: Element = this.domElement.querySelector('#divStatus');
  
    listContainer.innerHTML = html;
    });
  }

private readListItem(id): void {

    this._getListItemByID(id).then(listItem => {

    document.getElementById("txtSoftwareTitle")["value"] = listItem.Title;
    document.getElementById("ddlSoftwareVendor")["value"] = listItem.SoftwareVendor;
    document.getElementById("txtSoftwareDescription")["value"] = listItem.SoftwareDescription;
    document.getElementById("txtSoftwareName")["value"] = listItem.SoftwareName;
    document.getElementById("txtSoftwareVersion")["value"] = listItem.SoftwareVersion;
    
    
    })
    .catch(error => {
      let message: Element = this.domElement.querySelector('#divStatus');    
      message.innerHTML = "Read: Could not fetch details.. "+error.message;
    });
  }
OMGDrAcula
  • 1,054
  • 3
  • 11
  • 17
  • Where is `readListItem()` called? – rveerd Dec 02 '22 at 15:47
  • I added my call to the code. It is called on the edit button but in the code that gets compiled it says undefined, if I do it another way when I click the button it says readListItem is undefined. I tried doing it in the onclick attribute of the editButton – OMGDrAcula Dec 02 '22 at 15:59
  • 1
    Use `addEventListener` to attach the function to your element, or to an ancestor element, and check `event.target` to see if it is the element you want to target (a process known as ["event delegation"](/q/203198/)). Note that in `readListItem`, you are redefining `id` immediately, so you call `_getListItemByID` with the value of the element with and ID of "txtID", rather than the argument. – Heretic Monkey Dec 02 '22 at 16:12
  • Oh I should have removed that line. I have an array of buttons that get created during the forEach of the listItems to build the table. But I could essentially still use your process to bind an addEventListener to the child buttons correct? – OMGDrAcula Dec 02 '22 at 16:16

0 Answers0