Home > Software engineering >  Is this NaNNaNNaN error caused by concatenation or something else?
Is this NaNNaNNaN error caused by concatenation or something else?

Time:08-16

When creating a HTML table using javascript it ends up showing "NaNNaNNaN" next to the table

NaNNaNNaN form the .innerHTML using html tag inside the script

multipe objects in the .innerHTML

Here's code:

 // Constructor function for Person objects
    function Person(first, last, relation, gender, age, eye) {
      this.firstName = first;
      this.lastName = last;
      this.relation = relation;
      this.gender = gender;
      this.age = age;
      this.eyeColor = eye;
    }
    // Create 2 Person objects
    const myFather = new Person("John", "Doe", "father", "Male", 50, "Blue");
    const myMother = new Person("Sally", "Rally","mother", "Female", 48, "Green");
    // Add a name method to first object
    myMother.name = function() {
      return "<table border= '2' align='center'>" 
      "<tr>" 
      "<th>" "First Name" "</th>" 
      "<th>" "Last Name" "</th>" 
      "<th>" "Age" "</th>" 
      "<th>" "Relation" "</th>" 
      "<th>" "Gender" "</th>" 
      "<th>" "Eye Color" "</th>" 
       "</tr>" 
      "<tr>" 
      "<td>" this.firstName "</td>" 
      "<td>" this.lastName "</td>" 
      "<td>" this.age "</td>" 
      "<td>" this.relation "</td>" 
      "<td>" this.gender "</td>" 
    
      "<td>" this.eyeColor "</td>" 
       "</tr>" 
       "</table>"
      };
    // Display full name
    document.getElementById("demo").innerHTML  =
    myMother.name(); 
<!DOCTYPE html>
    <html>
    <body>
    <h2>JavaScript Object Constructors</h2>
    <p id="demo">
    </p> 
    </body>
    </html>

here's output

CodePudding user response:

As mplungjan says, you have too many plus signs, but here is what is happening and why:

When you have this snippet, the result is </tr>NaN.

console.log("</tr>"        "</table>" )

Why? Because of forced type coercion. The extra plus sign forces numeric conversion of a string, so "</table>" becomes a number. An invalid number in this case (NaN = Not a Number).

1   "1"
> '11'
1    "1"
> 2
1     "not a number"
> NaN
"a string"     "not a number"
> 'a stringNaN'

So why does the table still render? Because of a permissive DOM rendering model. If some nodes are missing the browser will still try to render the resulting DOM nodes, completing missing end tags as required.

CodePudding user response:

You have typos (too many ). But you really want something like this

Why only have a table row function for the mother?

function Person(first, last, relation, gender, age, eye) {
  this.firstName = first;
  this.lastName = last;
  this.relation = relation;
  this.gender = gender;
  this.age = age;
  this.eyeColor = eye;
  this.name = () => `
    <tr>
      <td>${this.firstName}</td>
      <td>${this.lastName}</td>
      <td>${this.age}</td>
      <td>${this.relation}</td>
      <td>${this.gender}</td>
      <td>${this.eyeColor}</td>
    </tr>`;
};

// Create 2 Person objects
const myFather = new Person("John", "Doe", "father", "Male", 50, "Blue");
const myMother = new Person("Sally", "Rally", "mother", "Female", 48, "Green");
// Display full name
document.getElementById("demo").innerHTML  = myMother.name();
document.getElementById("demo").innerHTML  = myFather.name();
thead
<table border='2' align='center'>
  <thead>
    <tr>
      <th>First Name</th>
      <th>Last Name</th>
      <th>Age</th>
      <th>Relation</th>
      <th>Gender</th>
      <th>Eye Color</th>
    </tr>
  </thead>
  <tbody id="demo"></tbody>
</table>

CodePudding user response:

Here's your updated code. I'm using Template Literals syntax. Learn more about Template Literals here. I've minimized your code so that you can add new rows in the table instead of repeating the whole table for each new entry.

function Person(first, last, relation, gender, age, eye) {
  this.firstName = first;
  this.lastName = last;
  this.relation = relation;
  this.gender = gender;
  this.age = age;
  this.eyeColor = eye;
  this.name = () => `
    <tr>
      <td>${this.firstName}</td>
      <td>${this.lastName}</td>
      <td>${this.age}</td>
      <td>${this.relation}</td>
      <td>${this.gender}</td>
      <td>${this.eyeColor}</td>
    </tr>`;
};

// Create 2 Person objects
const myFather = new Person("John", "Doe", "Father", "Male", 50, "Blue");
const myMother = new Person("Sally", "Rally", "Mother", "Female", 48, "Green");
const myBrother = new Person("Alex", "Doe", "Brother", "Male", 48, "Black");
// Display full name
document.getElementById("demo").innerHTML = myMother.name();
document.getElementById("demo").innerHTML  = myFather.name();
document.getElementById("demo").innerHTML  = myBrother.name();
<!DOCTYPE html>
<html>

<body>
  <h2>JavaScript Object Constructors</h2>
  <table border='2' align='center'>
    <thead>
      <tr>
        <th>First Name</th>
        <th>Last Name</th>
        <th>Age</th>
        <th>Relation</th>
        <th>Gender</th>
        <th>Eye Color</th>
      </tr>
    </thead>
    <tbody id="demo"></tbody>
  </table>
</body>

</html>

CodePudding user response:

permit me to Add... why not use interpolation with Template Literals on your variables, utilization of back ticks...

`<td> ${this.firstName} </td>
 <td> ${this.lastName} </td>`

its going to save you a lot of stress, and you can get rid of the concatenation signs.

  • Related