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

Here's my solution (I got a little bit carried away)

This code achieves several objectives. It checks that the name is in the db when it is submitted in the prompt box and warns the user if it isn't. It also allows for upper and lower cases name entries to be checked. It does this by looping through the data and building an array of all the names in the original array in lower case through which I search. Then, I created a multi dimensional array of all the names entered at the prompt box (meaning you can ask the script to search for more than one name) pulling in the additional data from the original array. It wasn't necessary in order for this to work (as you can see from other examples posted here I could have just created a variable and added on to that each through each loop), but it loops through each element in the array to the variable output. Then I use the print() function to display the html on the page. I've included an instruction in the code to send the new arrays to the console so you can see them for yourself.

var html = '';            // Output results
var searchTerm = '';      // Input at the prompt screen, accepts lower case names as well
var student;              // Variable holding students matched from the list
var names = [];           // Array holding the names of all those in the database
var list = [];            // Array holding the names of all matches

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

// Array of student data
var students = [
  { name: 'Andrea', track: 'iOS', achievements: 5, points: 460 },
  { name: 'Brenda', track: 'PHP', achievements: 23, points: 1000 },
  { name: 'Caroline', track: 'CSS', achievements: 43, points: 1250 },
  { name: 'Deidre', track: 'Database', achievements: 16, points: 2542 },
  { name: 'Andrea', track: 'Front End Development', achievements: 9, points: 350 }
]

// This function tests to see if a name is in the students database (by creating an array of names in lower case it is also able to check regardless of whether a name is entered in lower case)
function isName( who ) {
  for ( var i = 0; i < students.length; i++ ) {
    names.push(students[i].name.toLowerCase());
  }
  console.log(names);
  who = who.toLowerCase();
  if ( names.indexOf(who) <0 ) {
    alert('Nope, not a name');
  }
}

// This function creates a new array of the names that have been entered at the prompt dialog
function listOutput( searchTerm ) {
  for ( var i=0; i < students.length; i++ ) {
    student = students[i];
    if ( student.name.toLowerCase() === searchTerm.toLowerCase() ) {
      list.push([students[i].name, students[i].track, students[i].achievements, students[i].points]);
    }
  }
  console.log(list);
}

// This function takes the values in the array created and loops through them to produce the output html
function getStudentReportList ( student ) { 
  var report = '<h2>' + list[i][0] + '</h2><br>';
  report += 'Track: ' + list[i][1] + '<br>';
  report += 'Achievements: ' + list[i][2] + '<br>';
  report += 'Points: ' + list[i][3];
  return report;
}

while (true) {
  searchTerm = prompt('Enter a name to search for or type quit to exit');
  if ( searchTerm === null || searchTerm.toLowerCase() === 'quit' ) {
    break;
  }
  isName(searchTerm);           // Calls the function to check a name is present 
  listOutput(searchTerm);       // Calls the function to add the name to a new array
}

// Loops through search results and prints them out
for ( var i=0; i < list.length; i++) { 
  html += getStudentReportList( student );
  print(html);
}

To reiterate, the multidensional array I created of the search results wasn't necessary to get this to work as you will see from other solutions. I made it multidimensional as opposed to another array of objects because the course hadn't yet shown how to push these results into a new array of objects so I used a multidimensional one instead.

I could have created an array of matching id's, then looped through this array and pulled the data from the original array and may update to add that at some stage.

Thank you so much for sharing. I appreciate it a lot; was really stuck.

3 Answers

David Leininger
David Leininger
13,034 Points

You're correct. I missed that you were doing html += during the loop. So basically, I just did a little bit of refactoring, haha. Good work on this.

No problem, I really appreciate the feedback. That's why I posted the code. I'm here to figure out how to improve what I've written. There's a bunch of things going on here that weren't necessary in order to do the job, I was really just playing around haha.

while (true) { searchTerm = prompt('Enter a name to search for or type quit to exit'); if ( searchTerm === null || searchTerm.toLowerCase() === 'quit' ) { break; } isName(searchTerm); /

The function isName is passed the argument (searchTerm) but I see that isName only takes 'who' as a parameter therefore I do not understand how searchTerm is passed to function isName(who), could someone exlpain please?

Without wishing to avoid giving an answer, try changing the argument 'who' to 'searchTerm' yourself and see if doing so breaks anything. Sometimes the best way to get a handle on what works and doesn't is playing around with the code.

David Leininger
David Leininger
13,034 Points

This only prints out the last student report with the searched name. Since print(html) is called every time the for loop runs the html is replaced. You need to run the loop that calls getStudentReport() inside of listOutput() to insure it prints every matching name to the page.

function listOutput(search) {
  for (i = 0; i < students.length; i += 1) {
    var student = students[i];
    if (student.name.toLowerCase() === search.toLowerCase()) {
      list.push([
        students[i].name, 
        students[i].track,
        students[i].achievements,
        students[i].points
      ]);
    }
  }
  console.log(list);
// Putting the loop here and taking print(html) out of the loop allows you to print all matching searches.
  for (i = 0; i < list.length; i += 1) {
    html += getStudentReport();
  }
  print(html);
}

You'll want to make sure you reset your list array at the end of the while loop so it doesn't double print your results with multiple searches. The same goes for the names array, though if the data isn't going to change, you could just take the for loop where you push the names out of the function and put it before the while loop. That way it only runs once:

// for loop from isName function this way it only runs once. Could leave it where it is and just do name = []; below
for (i = 0; i < students.length; i += 1) {
  names.push(students[i].name.toLowerCase());
}

while (true) {
  search = prompt('Search for a student. Type "quit" to stop searching.');
  if (search === null || search.toLowerCase() === 'quit') {
    break;
  }
  isName(search);
  listOutput(search);
  list = []; // Clears the list array so that it's empty next time the loop runs and doesn't duplicate data
}

The same could be said for html if you only wanted to display the current search results. You just clear the variable at the end of the loop.

Sorry. I think I may have gone a little overboard as well. A little refactoring.

This only prints out the last student report with the searched name.

Are you sure? I've just checked it again and it works exactly as described finding both multiple entries and allowing a user to query multiple students.

True, print(html) running inside the loop versus outside the loop is less efficient, but it doesn't alter the output after quit is typed and hasn't led to any duplications that I've seen.