Gerrit
Gerrit

Reputation: 29

How to display a json response in a html table

I know the problem is the data.map. Maybe its because map is made for arrays and i have an array of objects and not a array?

API-Response:

[
  {
    "id": 16,
    "nachname": "Köpper",
    "vorname": "Chris",
    "projectList": []
  },
  {
    "id": 13,
    "nachname": "Kämpfer",
    "vorname": "Gerrit",
    "projectList": [
      {
        "id": 9,
        "name": "FB.de"
      },
      {
        "id": 7,
        "name": "DFBnet"
      }
    ]
  },
  {
    "id": 12,
    "nachname": "Voges",
    "vorname": "Arved",
    "projectList": [
      {
        "id": 9,
        "name": "FB.de"
      },
      {
        "id": 7,
        "name": "DFBnet"
      }
    ]
  }
]

HTML-Table:

<table class="table" id="output1">
        <thead>
            <tr>
                <th scope="col">ID</th>
                <th scope="col">Vorname</th>
                <th scope="col">Nachname</th>
            </tr>
        </thead>
        <tbody>

        </tbody>

    </table>

js:

function getPerson(){
fetch(url)
    .then(res => res.json())
    .then(data => {
        var tableContent = document.querySelector('#output1 > tbody');
        data.map(function(instance) {
            const row = document.createElement('tr');
            tableContent.appendChild(row);
            instance.map(function(info) {
                const cell = document.createElement('td');
                cell.innerText = info;
                row.appendChild(cell);
            });
        });
    })
}

Upvotes: 0

Views: 612

Answers (3)

Aman
Aman

Reputation: 868

No, the problem is not with data.map, because the map function works on any kind of array whether it is plain array or array of objects.The problem in your code is regarding the instance.map , since the individual element of data array is an object. Therefore either we can use for...in statement as below

function getPerson() {
      fetch(url)
      .then(res => res.json())
      .then(data => {
        var tableContent = document.querySelector('#output1 > tbody');
        data.map(function (instance) {
          const row = document.createElement('tr');
          tableContent.appendChild(row);
          for (key in instance) {
            if (key !== 'projectList') {
              const cell = document.createElement('td');
              cell.innerText = instance[key];
              row.appendChild(cell);
            }
          }
        });
      })
    }

Upvotes: 0

Alwin Kesler
Alwin Kesler

Reputation: 1520

I've made a jsfiddle to help you out. Map is for array, so you're missing one step (iterate object attributes, one for cell).

let content = [{
    "id": 16,
    "nachname": "Köpper",
    "vorname": "Chris",
    "projectList": []
  },
  {
    "id": 13,
    "nachname": "Kämpfer",
    "vorname": "Gerrit",
    "projectList": [{
        "id": 9,
        "name": "FB.de"
      },
      {
        "id": 7,
        "name": "DFBnet"
      }
    ]
  },
  {
    "id": 12,
    "nachname": "Voges",
    "vorname": "Arved",
    "projectList": [{
        "id": 9,
        "name": "FB.de"
      },
      {
        "id": 7,
        "name": "DFBnet"
      }
    ]
  }
]


function getPerson() {
  Promise.resolve(content)
    //fetch(url).then(res => res.json())
    .then(data => {
      var tableContent = document.querySelector('#output1 > tbody');
      data.map(function(instance) {
        const row = document.createElement('tr');

        for (let c of ['id', 'nachname', 'vorname']) {
          let cell = document.createElement('td');
          if (instance.hasOwnProperty(c)) {
              cell.innerText = instance[c]
          }

          row.appendChild(cell)
        }

        tableContent.appendChild(row)
      });
    })
}

getPerson()
<table class="table" id="output1">
  <thead>
    <tr>
      <th scope="col">ID</th>
      <th scope="col">Vorname</th>
      <th scope="col">Nachname</th>
    </tr>
  </thead>
  <tbody>
  </tbody>
</table>

Upvotes: 1

sdotson
sdotson

Reputation: 820

If data is an array of objects, then instance is one single object within that array. You can't map over an object directly. If you are trying to create a table cell for each key/value pair, I would suggest looking at Object.values() or Object.entries to create the array that you can then iterate (map) over.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries

Something like:

Object.values(instance).map(function(info) {
  const cell = document.createElement('td');
  cell.innerText = info.toString();
  row.appendChild(cell);
});

Although you would need to decide how you want to represent projectList in the table as well, perhaps by iterating again and creating an inner table or concatenating the values together to a string.

If I'm missing something important about your use case, feel free to comment and I'll amend my answer.

Upvotes: 1

Related Questions