Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript JavaScript Loops, Arrays and Objects Tracking Data Using Objects The Build an Object Challenge, Part 2

fngr
fngr
11,179 Points

Get stuck: Uncaught TypeError: Cannot read property 'name' of undefined

I don't know what I'm doing wrong in this challenge. I just get the error from my title.

This is my code:

var students = [ 
  { 
   name: 'Dave',
    track: 'Front End Development',
    achievements: 158,
    points: 14730
  },
  {
    name: 'Jody',
    track: 'iOS Development with Swift',
    achievements: '175',
    points: '16375'
  },
  {
    name: 'Jordan',
    track: 'PHP Development',
    achievements: '55',
    points: '2025'
  },
  {
    name: 'John',
    track: 'Learn WordPress',
    achievements: '40',
    points: '1950'
  },
  {
    name: 'Trish',
    track: 'Rails Development',
    achievements: '5',
    points: '350'
  }
];

function print(message) {
  document.getElementById("output").innerHTML = message;
}

for (var i = 0; i < students.length; i += 1) {
  for (var prop in students[i]) {
    var student = "<h2>Name: " + prop[i].name + "</h2>";
    student += "<p>Track: " + prop[i].track + "</p>";
    student += "<p>Achievements: " + prop[i].achievements + "</p>";
    student += "<p>Points: " + prop[i].points + "</p>";
    print(student);
  }
}

3 Answers

Steven Parker
Steven Parker
229,732 Points

You have a couple of issues here:

  • Your iteration produces the indexes of each student property, but you are using it as if it were the student object.
  • Your print function replaces the output contents each time, wiping out the previous set of values.

You could fix the first problem as Chyno suggested (but eliminate the redundant outer loop!), or you could loop through the objects themselves, like this:

for (var stud of students) {    // <-- note "of" instead of "in"
    var student = "<h2>Name: " + stud.name + "</h2>";
    student += "<p>Track: " + stud.track + "</p>";
    student += "<p>Achievements: " + stud.achievements + "</p>";
    student += "<p>Points: " + stud.points + "</p>";
    print(student);
}

The second problem could be handled by declaring student outside the loop, appending everything, and then calling print after the loop. Or you could just append the contents of output inside the print function:

function print(message) {
    document.getElementById("output").innerHTML += message;  // append instead of overwrite
}
Parker Brown
Parker Brown
24,308 Points

Steven Parker was wondering for this exercise we're iterating thru an array literal, students, correct? We could also have just used a for (var i=0; i<students.length; i++) loop { student = students[i]; msg += ...;} to print out this this array of objects and the objects' contents, right?

Matt F.
Matt F.
9,518 Points

Hello fngt,

After updating the loop to remove the error, you will receive output to the page that is the last student in the array of objects - Trish. This is because each loop is calling print, overwriting the previous student's information almost instantaneously. One way to remedy this is to continue adding the new student to the previous inner html of the output div, like this:

function print(message) {
  document.getElementById("output").innerHTML += message;
}
Steven Parker
Steven Parker
229,732 Points

Matt, it looks like you only read part of my answer. :disappointed:

Matt F.
Matt F.
9,518 Points

That is true, lol. May want to note that for... of is not available in IE (pre-Edge) though ;)

fngr
fngr
11,179 Points

Thank you all! You're great! Here is my new working script. What do you think?

// ...

function print(message) {
  document.getElementById("output").innerHTML = message;
}

var studentList = [];

for (var prop of students) {
  var student = "<h2>Name: " + prop.name + "</h2>";
  student += "<p>Track: " + prop.track + "</p>";
  student += "<p>Achievements: " + prop.achievements + "</p>";
  student += "<p>Points: " + prop.points + "</p>";
  studentList.push(student);
}

print(studentList.join(''));
Matt F.
Matt F.
9,518 Points

It looks good - nice work.

Just take note that if you use for... of in a project that will be published, you will want to use a transpolar (like Babel) as it was added to the JavaScript specification recently and older browsers do not support it.

fngr
fngr
11,179 Points

Thank you @mattfricker2 โ€“ good to know!