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

Nicholas Woods
Nicholas Woods
6,260 Points

Just wondering if there was any way to make this any better. Have been fiddling around with it for a long time.

This challenge did my head in trying to get the alert for an incorrect search.

student_report.js
var message = '';
var studentA;
var search;
var indexOfStudent;

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

function formatS(student) {
  message = '<h2>Student :  ' + student.Name + '</h2>';
  message += '<p> Track :  ' + student.Track + '</p>';
  message += '<p> Achievements :  ' + student.Achievements + '</p>';
  message += '<p> Points :  ' + student.Points + '</p>';
  print(message);
}

function indexByKey(array, value) {
    for (var i = 0; i < array.length; i++) {
        if (array[i].Name === value) {
            return array[i];
        }
    }
    return null;
}

while (true) {
  search = prompt('Search the student database to find their record. Type "quit" to quit.');
  if (search === null || search === 'quit') {
    break;
  } else {
    for (var i = 0; i < students.length; i++) {
      studentA = students[i];
      if (search === studentA.Name) {
        formatS(studentA); 
      } else {
        indexOfStudent = indexByKey(students, search);
        if (indexOfStudent === null) {
          alert('Sorry, there is no student registered by the name of ' + search); 
          break;
        }
      }
    }
  }
}

6 Answers

I think you can get rid of the indexByKey() function all together. The way you have this written now the for loop will only run once because it's either matching the student ont he first try or calling the indexByKey functon and then breaking aftering its done.

for (var i = 0; i < students.length; i++) {
      studentA = students[i];
      if (search === studentA.Name) {
        formatS(studentA); 
      } else {
        indexOfStudent = indexByKey(students, search);
        if (indexOfStudent === null) {
          alert('Sorry, there is no student registered by the name of ' + search); 
          break;

I would get rid of the indexByKey() function. For the alert you can check to see if i you are on the last loop and if you get to the end of the last loop then post the alert so something like this at bottom of your while loop:

if (i === (students.length - 1) {
  alert('Sorry, there is no student registered by the name of ' + search); 
  break;
}

Let me know if that isn't clear enough and I can actually type out what I think that code should look like.

Nicholas Woods
Nicholas Woods
6,260 Points

Yea I tried something like this, but even if the name is in the array it says 'no student'. That was why I took it out of the loop altogether.

You'd have to make sure that if a name is found it breaks from the loop so that it doesn't get to the end and say no student.

Nicholas Woods
Nicholas Woods
6,260 Points

Yea, that worked a treat. This is the final loop.

while (true) {
  search = prompt('Search the student database to find their record. Type "quit" to quit.');
  if (search === null || search === 'quit') {
    break;
  } else {
    for (var i = 0; i < students.length; i++) {
      studentA = students[i];
      if (search === studentA.Name) {
        formatS(studentA);
        break;
      } else if (i === students.length -1) {
          alert('Sorry, there is no student registered by the name of ' + search); 
      }
    }
  }
}

Perfect, much easier to follow now. The only other thing I'd change, but is purely stylistic would be to get rid of the studentA variable.

for (var i = 0; i < students.length; i++) {
      if (search === students[i]) {
        formatS(students[i]);

Personally for me thats easier to follow but again that's just a style choice.

Nicholas Woods
Nicholas Woods
6,260 Points

Thanks Victor, I will keep all that in mind.

Leigh Maher
Leigh Maher
21,830 Points

Can somebody explain what this condition is checking:

i === students.length -1

Instead of the above, I used something that made more sense to me, and it worked:

students.indexOf (search) < 1
Nicholas Woods
Nicholas Woods
6,260 Points

It's making sure the loop has run through the full array before using what's in the conditional statement. I tried what you have first, but it kept throwing out the conditional statement even if the name was in the array, as well as printing the name to the page. Can you paste your code? I'm interested to see how you tackled it.

Leigh Maher
Leigh Maher
21,830 Points

Thanks Nicolas. That makes sense now.

I've just tested my code again and just realized that it wasn't actually working as it should. It only works for the first name in my array. Any subsequent names I enter get the message "Sorry, there is no student here by the name", whether they're in the array or not. Seems like it should work, but I must be missing something. Here's my code anyway:

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

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

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

while (true) {
  search = prompt ('Please enter a students name, or type "quit" to exit');
  if (search === null || search.toLowerCase() === 'quit') {
    break;
  }  
  for (var i = 0; i < students.length; i++) {
  student = students[i];
  if (search.toLowerCase() === student.name.toLowerCase()) {
    message = getStudentReport (student);
    print (message);
    break;
    } else if (students.indexOf(search) < 1) {
      alert ('Sorry, there is no student here by the name ' + search);
      break;
    }
  } 
}
Nicholas Woods
Nicholas Woods
6,260 Points

looks like you're having the same problem I did. Good that you tested it. This frustrated me for a long time. My first solution was using a function which worked, but I wanted to know why it wasn't working in the loop, so I asked. The for loop needs to check all the name values in the array before throwing out the error.

Leigh Maher
Leigh Maher
21,830 Points

Yes, and the else statement is in the loop so it seems like it should work. Hopefully, someone else can shed some light on it. Thanks Nicolas.

Edwin Alvarez
Edwin Alvarez
4,903 Points

In order to fix that, right after you print the message set i = students.length + 1; that way it will end the loop right away without breaking the prompt.