Fabio Torti
Fabio Torti

Reputation: 71

Javascript grab the data from the table in the HTML and build an array of objects that contains the table data

I have an HTML table and I need to define a function that should grab the data from the table and build an array of objects that contains table data. Outside the function I have to declare a variable and assign the returned value from the function.

Thanks in advance.

HTML

<table>
    <thead>
        <tr>
            <th>Name</th>
            <th>Rating</th>
            <th>Review</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>Bob</td>
            <td>5/5</td>
            <td>This product is so good, I bought 5 more!</td>
        </tr>
        <tr>
            <td>Jane</td>
            <td>4/5</td>
            <td>Good value for the price.</td>
        </tr>
        <tr>
            <td>David</td>
            <td>1/5</td>
            <td>Arrived broken :(</td>
        </tr>
        <tr>
            <td>Fiona</td>
            <td>5/5</td>
            <td>I love it!</td>
        </tr>
        <tr>
            <td>Michael</td>
            <td>3/5</td>
            <td>Doesn't live up to expectations.</td>
        </tr>
    </tbody>
</table>

JS

function buildTableData() {
    let tbody = document.getElementsByTagName("tbody")[0];
    let rows = tbody.children;
    let people = [];

    for (let row of rows) {
        let person = {};

        let cells = row.children;
        person.rating = cells[0].textContent;
        person.review = cells[1].textContent;
        person.favoriteFood = cells[2].textContent;
        people.push(person);
        return people;
    }
    let data = people;
    console.log(data);
}

Upvotes: 1

Views: 1443

Answers (3)

Mamun
Mamun

Reputation: 68933

You can try using querySelectorAll() and map() like the following way:

function buildTableData() {
  let rows = document.querySelectorAll('tbody tr');
  let data = Array.from(rows).map(function(tr){
    return {
      rating: tr.querySelectorAll('td:nth-child(1)')[0].textContent,
      review: tr.querySelectorAll('td:nth-child(2)')[0].textContent,
      favoriteFood: tr.querySelectorAll('td:nth-child(3)')[0].textContent
    };
  });
  console.log(data);
}

buildTableData();
<h2>Product reviews</h2>

<table>
  <thead>
      <tr>
          <th>Name</th>
          <th>Rating</th>
          <th>Review</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Bob</td>
          <td>5/5</td>
          <td>This product is so good, I bought 5 more!</td>
      </tr>
      <tr>
          <td>Jane</td>
          <td>4/5</td>
          <td>Good value for the price.</td>
      </tr>
      <tr>
          <td>David</td>
          <td>1/5</td>
          <td>Arrived broken :(</td>
      </tr>
      <tr>
          <td>Fiona</td>
          <td>5/5</td>
          <td>I love it!</td>
      </tr>
      <tr>
          <td>Michael</td>
          <td>3/5</td>
          <td>Doesn't live up to expectations.</td>
      </tr>
  </tbody>
</table>

Upvotes: 1

Aalexander
Aalexander

Reputation: 5004

You can get all the elements by using querySelectorAll('td'). Then use map to to get only the text of it and return this.

function buildTableData() {
  const elements = [...document.querySelectorAll('td')];
  return elements.map(x => {
    return {content : x.innerHTML}
  });
}

console.log(buildTableData());
<body>

  <h2>Product reviews</h2>

  <table>
    <thead>
      <tr>
        <th>Name</th>
        <th>Rating</th>
        <th>Review</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Bob</td>
        <td>5/5</td>
        <td>This product is so good, I bought 5 more!</td>
      </tr>
      <tr>
        <td>Jane</td>
        <td>4/5</td>
        <td>Good value for the price.</td>
      </tr>
      <tr>
        <td>David</td>
        <td>1/5</td>
        <td>Arrived broken :(</td>
      </tr>
      <tr>
        <td>Fiona</td>
        <td>5/5</td>
        <td>I love it!</td>
      </tr>
      <tr>
        <td>Michael</td>
        <td>3/5</td>
        <td>Doesn't live up to expectations.</td>
      </tr>
    </tbody>
  </table>


  <script src="https://cdnjs.cloudflare.com/ajax/libs/acorn/7.3.1/acorn.js" integrity="sha512-4GRq4mhgV43mQBgKMBRG9GbneAGisNSqz6DSgiBYsYRTjq2ggGt29Dk5thHHJu38Er7wByX/EZoG+0OcxI5upg==" crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/acorn-walk/7.2.0/walk.js" integrity="sha512-j5XDYQOKluxz1i4c7YMMXvjLLw38YFu12kKGYlr2+w/XZLV5Vg2R/VUbhN//K/V6LPKuoOA4pfcPXB5NgV7Gwg==" crossorigin="anonymous"></script>
  <script src="index.js"></script>
</body>

Upvotes: 1

Da Mahdi03
Da Mahdi03

Reputation: 1608

You want a loop, and each review to be an object that is appended to an array of reviews is what I'm assuming

var reviews = [];

var tbody = document.querySelectorAll("tbody")[0];
var TRs = tbody.querySelectorAll("tr");
for (var a = 0; a < TRs.length; a++) {
    var TDs = TRs[a].querySelectorAll("td");
    var review = {
        name: "",
        rating: "",
        review: ""
    };
    //These assume the order of your table columns don't change
    review.name = TDs[0].innerHTML;
    review.rating = TDs[1].innerHTML;
    review.review = TDs[2].innerHTML;
    reviews.push(review);
}

Your reviews array should have everything in there just as you wanted. I assumed the third column was "review" instead of "favorite food"

Upvotes: 0

Related Questions