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

The Student Record Search Challenge - Student not found

At the end of the student record challenge, Dave asks us to figure out what to do if the user searches for a student not in the array.

I ended up adding the else clause which logically makes sense to me ... and I've commented out the code the way I understand it. Adding this else clause caused ALL searches to return the result "Sorry, searched name not found". When I comment out that else clause everything works perfectly.

For the life of me I can't figure out what I'm doing wrong.

Am hoping someone can help? Many thanks.

(Anyone preferring the workspace...here is the snapshot)

var message = '';
var student;
var search;

//access output div in the DOM
function print(message) {
  var outputDiv = document.getElementById('output');
  outputDiv.innerHTML = message;
}

//write the student report - all key value pairs from the specified array -- to the document
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) {  //creates an endless loop that breaks if the user types quit
  search = prompt('search student records: type a name [Jody] (or type "quit" to exit)');
  search = search.toLowerCase();
  if(search === null || search === 'quit') {
    break;
  }  
  for (var i = 0; i < students.length; i += 1) { //iterate through the object to search for name match
    student = students[i];  //access each array within the students object
    if( student.name.toLowerCase() === search ) { //if the value of the name property equals the search word
      message = getStudentReport( student ); //then run the student report on that student
      print(message); //and print it to the page
    } else {  //if not
      message = '<p>Sorry, ' + search + ' not found.</p>'; //set the message to be printed to the searched name
      print(message); //and print this message to the page
    }
  }
}

5 Answers

Your for loop is evaluating over each student, regardless of when you "find" the correct student in the loop. Your intent with the else statement may be to report back if every student is checked and there are no matches. However, it is currently reporting back after checking every single student. By removing the else clause, only the iteration that successfully matches the student to the search query will result in an answer being printed out, even though each student in the array is still checked.

Does that make sense?

Joseph Wasden Ok I THINK I understand...Can you let me know if I got this correctly? EACH search is iterating through the object. so though it finds Dave or Jody in the array it will print that they are not found because further into the array those dave or jody do not match john. therefore it's printing that Jody is not found... Am I understanding that correctly?

Also, if this is the case why doesn't it print BOTH Jody's Student Record as well as Jody not found?

Thanks so much for your help!

I typed a huge reply, but I think that would just confuse things a bit more. :) I think there may be some confusion around the for loop. Can you explain to me as best you can how this part of the code works? For example, how many times will it run? How will it determine when to stop?

for (var i = 0; i < students.length; i += 1) { 
    student = students[i];  
    if( student.name.toLowerCase() === search ) { 
      message = getStudentReport( student ); 
      print(message); 
    } else {  
      message = '<p>Sorry, ' + search + ' not found.</p>'; 
      print(message); 
    }
  }

The way I understand it, the if else with run all the way as many times as there are students in the array. so if there are 6 students in the array this should run a total of 6 times because the i counter is starting at 0. Is that correct?

Thanks!

Thats correct. Now, lets say we had typed in Dave in the console. Since Dave is in array position 0, it would be found first, and the print() method called would set the div to his report. Great!

but we still have the rest of the array to go, right? and since the remaining array items arent going to match Dave, they will call the print() method in the else block and write the not found message, replacing the correct match information that was set there earlier.

because this happens so fast, it has the illusion of having never found Dave at all. It did find Dave. and then it found all the others and wrote the not found message for each of those, overwriting the report for Dave message.

Does that make sense?

Yes that makes total sense. That's what I was trying to explain in yesterday's post (poorly). SO...in order to make that work, I have to take the else out of the loop and make it it's own thing...which is now why I understand -- there's another post in the community with one solution and I was wondering why he was keeping track of the not found names in a separate array. makes sense now. Thank you for taking the time to explain that!

lauralouise
lauralouise
14,853 Points

I was having the same problem, and the way I got out of it was placing the student-not-found scenario FIRST. so an error message would be written to the page if the search term didn't match. otherwise, it would search and display the results.

while (true) { searchName = prompt("Please type the name of a student to access their records or type 'quit' to end program");

if ( searchName === null || searchName.toLowerCase() === 'quit'){ break; } for ( var i = 0; i < students.length; i += 1){ student = students[i];

if (student.name !== searchName){ print("no dice")} else if ( student.name === searchName ){ message = getStudentReport( student ); print(message); break; } } }

You could check if there was any student found before printing the 'not found' string, too:

    if( student.name.toLowerCase() === search ) { 
      message = getStudentReport( student ); 
      print(message);
      studentFound = true;
    } else if (!studentFound) {  
      message = '<p>Sorry, ' + search + ' not found.</p>'; 
      print(message);
    }

and reset the variable to false after each search query.