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 Student Record Search Challenge Solution

To display multiple students by same name

There could be different ways to solve this, but here's my quick attempt on Dave's code:

var message;
var student;
var search;

function print(message) {
  var outputDiv = document.getElementById('output');
  outputDiv.innerHTML = message;
}

function getStudentReport( student ) {
  var report = '<h2>Student: ' + student.name + '</h2>';
  report += '<p>Track: ' + student.track + '</p>';
  report += '<p>Points: ' + student.points + '</p>';
  report += '<p>Achievements: ' + student.achievements + '</p>';
  return report;
}

while (true) {
  message = '';
  search = prompt('Search student records: type a name [Jody] (or type "quit" to end)');
  if (search === '') {
    continue;
  }
  // search = search.toLowerCase(); - fixed as per Iain's suggestion below
  if (search === null || search.toLowerCase() === 'quit') {
    break;
  }
  for (var i = 0; i < students.length; i += 1) {
    student = students[i];
    if ( student.name.toLowerCase() === search.toLowerCase()) {
      message += getStudentReport( student );
    }
  }
  if (message !== '') {
    print(message);
  } else {
    message += 'Student "' + search + '" has no records!';
    print(message);
  }
}

This also addresses the empty or non-existing student name.

1 Answer

Good job! The only thing is, because you convert search to lowercase before you check if it is equal to null, you would still get the error that it doesn't have the property toLowerCase. You instead need to check if it is equal to null or if converted to lowercase is equal to 'quit'.

Here's my solution, which has some similarities, but also allows for students whose names contain the search term, not just match it exactly.

var html = '';

function print(nodeID, message) {
  document.getElementById(nodeID).innerHTML = message;
}

function buildDefinitionList(obj) {
  var prop;
  var dListHTML = '<dl>';
  for (prop in obj) {
    dListHTML += '<dt>' + prop.charAt(0).toUpperCase() + prop.slice(1) + '</dt>';
    dListHTML += '<dd>' + obj[prop] + '</dd>';
  }
  dListHTML += '</dl>';
  return dListHTML;
}

function buildStudentList(list) {
  var i;
  var uListHTML = '<ul>';
  for (i = 0; i < list.length; i++) {
    uListHTML += '<li>' + buildDefinitionList(list[i]) + '</li>';
  }
  uListHTML += '</ul>';
  return uListHTML;
}

function getMatchingStudents(list) {
  var query;
  var i;
  var resultList;
  // keep looping until the user quits
  while(true) {
    // reset the result list
    resultList = [];
    // prompt and convert to lowercase
    query = prompt("Search student records: type a name [Iain] (or type 'quit' to end)");
    // check if they want to quit
    if (query === null || query.toLowerCase() === 'quit') {
      break;
    }
    // loop through students and check if the name contains the search query
    for (i = 0; i < list.length; i++) {
      if (list[i].name.toLowerCase().indexOf(query.toLowerCase()) > -1) {
        // if so, push to the result list
        resultList.push(list[i]);
      }
    }    
    // if there are results
    if (resultList.length > 0) {
      // build the list of matching students
      html = buildStudentList(resultList);
    } else {
      // otherwise print a friendly not found message
      html = '<p>Sorry, there are no students matching that name</p>';
    }    
    // print html to output div
    print('output', html);
  }
}

getMatchingStudents(students);

That's a good point, Iain. Thanks for sharing! :)