Judgeharm Judgeharm - 1 month ago 5
Javascript Question

Add Array Objects to HTML Table

I am trying to add objects to this set of HTML code.

<div id="output">
<table id="presidents">
<tr>
<th>President</th><th>Took office</th><th>Left office</th>
</tr>
</table>
</div>



  • Write a function displayTable(presidents) which takes an array of
    president objects. Each president object has the properties name,
    tookOffice, leftOffice.

  • For each president add a row to the table with id "presidents"

  • Place the name in the first column, tookOffice in the second column,
    and leftOffice in the third column.



So far this is as close as I have gotten:

var x = document.getElementById('President');
var y = document.getElementById('Took Office');
var z = document.getElementById('Left Office');

function displayTable(presidents) {
var presArray = [{
name: 'W',
tookOffice: '2000',
leftOffice: '2008'
}, {
name: 'Obama',
tookOffice: '2008',
leftOffice: '2016'
}];
for (var i = 0; i < presArray.length; i++) {
x = +presArray[i].name;
y = +presArray[i].tookOffice;
z = +presArray[i].leftOffice;
}
}

Answer

Your current code

ID elements

Let's start off by seeing where you've gone wrong:

var x = document.getElementById('President');
var y = document.getElementById('Took Office');
var z = document.getElementById('Left Office');

You're thinking of each of the headers as IDs - the only one that has an ID is the table, because it has

<table id="presidents">

as the attribute. Because you're going to have to create a new row anyway, this isn't the right way to go about it. If that was indeed the case that the IDs corresponded to the table headers, you'd just be overwriting the headers, which of course is wrong. What happens when you run document.getElementById, passing an ID that exists, say:

document.getElementById('presidents'); // capitalisation matters!

is that a JavaScript object that represents the HTML of the <table id="presidents"> element is returned. Using this object, you can call various methods (such as appendChild()) and also properties like innerHTML and outerHTML, which returns the stringifed representation of the element.

For an example HTML file like this:

<!DOCTYPE html>
<html>
<head>
    <title>Test page</title>
</head>
<body>
    <div id="example">This is an example document.</div>
</body>
</html>

Calling innerHTML on the div element with ID example will yield the following:

document.getElementById('example').innerHTML; // 'This is an example document.'
document.getElementById('example').outerHTML; // '<div id="example">This is an example document.</div>'

You can also assign to these properties (which updates the respective HTML of that element), however it's not always the best idea (due to security concerns), and especially bad in production environments. For a university course though or just a simple hobby project, it should suffice for now.

Assigning values

for (var i = 0; i < presArray.length; i++) {
    x = +presArray[i].name;
    y = +presArray[i].tookOffice;
    z = +presArray[i].leftOffice;
}

Here, instead of adding to the header row (which it makes it messy and does not produce the result intended), you've actually done something completely different - you've made the various variables into something else.

The unary + operator (a + before a value or a variable, without something else on the left of the +) actually coerces the value into a number, which means that it will attempt to convert it into a number, and if not, make it NaN (not a number). For example, see these:

var a = 'random text';
var b = '1234567890';

+1; // 1
+'fefefjejfj'; // NaN
+Infinity; // Infinity
+-Infinity; // -Infinity
+''; // 0
+null; // 0
+undefined; // NaN
+'1.1'; // 1.1
+window; // NaN
+a; // NaN
+b; // 1234567890

If you need to manipulate strings, you need to use the += operator:

var a = 'test';
a += ' string';
a; // 'test string'

However, since you need to write this to the HTML instead of just working with JavaScript variables, what you actually need to be doing is appending new rows to your table, instead of overwriting variables. This can be done using the DOM - there are numerous reference guides and tutorials out there if you need some more help with it.

Your array

var presArray = [{
    name: 'W',
    tookOffice: '2000',
    leftOffice: '2008'
}, {
    name: 'Obama',
    tookOffice: '2008',
    leftOffice: '2016'
}];

The task that you've been given asks for a presidents variable for the argument. This means that you should pass the array when you call the function, not create one inside the function.

A method of passing an array as a argument is like the following:

var x = [ { y: 1 } ];

function test(arg) { return arg[0].y; }

test(x); // 1

Example code

Here's my implementation of the requirements - take the idea of how it works and apply that to your own work.

function displayTable(presidents) {
  // get the table to add rows to
  var table = document.getElementById('presidents');

  // cycle through the array for each of the presidents
  for (var i = 0; i < presidents.length; ++i) {
    // keep a reference to an individual president object
    var president = presidents[i];

    // create a row element to append cells to
    var row = document.createElement('tr');

    // properties of the array elements
    var properties = ['name', 'tookOffice', 'leftOffice'];

    // append each one of them to the row in question, in order
    for (var j = 0; j < properties.length; ++j) {
      // create new data cell for names
      var cell = document.createElement('td');

      // set name of property using bracket notation (properties[j] is a string,
      // which can be used to access properties of president)
      cell.innerHTML = president[properties[j]];

      // add to end of the row
      row.appendChild(cell);
    }

    // add new row to table
    table.appendChild(row);
  }
}

I've placed a live example of this working on JSFiddle - JSFiddle allows others to show examples and change them as they like.

Comments