Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

JavaScript JavaScript Loops, Arrays and Objects Tracking Data Using Objects The Student Record Search Challenge Solution

Heather Scroggins
Heather Scroggins
30 Points

First part of "while" loop not working

Alright....I have most of the code for this challenge working except for the first part of my while loop. The 'quit' and 'all' commands work perfectly fine but anything else I type goes to the last 'else' statement that declares a name is not in the database. Any and all help would be greatly appreciated.

Here is the students array that is housed in a separate .js file from the actual running code:

var students = [
  {
    name: 'John',
    track: 'Front End Web Development',
    achievements: 2,
    points: 6958
  },
  {
    name: 'Bob',
    track: 'Ruby',
    achievements: 6,
    points: 2316
  },
  {
    name: 'Susie',
    track: 'Python',
    achievements: 8,
    points: 4698
  },
  {
    name: 'Lional',
    track: 'iOS Development',
    achievements: 4,
    points: 5673
  },
  {
    name: 'Reg',
    track: 'JavaScript',
    achievements: 16,
    points: 106983
  }
];

And here is the code that actually runs:

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

var searchResponse;
var message = '';
var student;

while(true) {
  searchResponse = prompt("Welcome to the Student Search Engine(SSE). To find a student type the name below. To list all students in the SSE type 'all' (This will also exit the SSE). To exit the SSE type 'quit'.");
  searchResponse = searchResponse.toLowerCase();
  for (i = 0; i < students.length; i++) {
    student = students[i];
    if (student.name === searchResponse) {
      message = '<h2>Student: ' + student.name + '</h2>';
      message += '<p>Track: ' + student.track + '<br>';
      message += 'Achievements: ' + student.achievements + '<br>';
      message += 'Points: ' + student.points + '</p>';
    }
  }
  if (searchResponse === 'quit') {
    message = "Thank you for using the SSE.";
    print(message);
    break;
  } else if (searchResponse === 'all') {
    for (i = 0; i < students.length; i++) {
      message += '<h2>Student: ' + students[i].name + '</h2>';
      message += '<p>Track: ' + students[i].track + '<br>';
      message += 'Achievements: ' + students[i].achievements + '<br>';
      message += 'Points: ' + students[i].points + '</p>';
    }
    print(message);
    break;
  } else {
    message = "Sorry, that student isn't in the database. Please try a different name.";
    print(message);
  }
}

Thanks!

3 Answers

Jason Berteotti
Jason Berteotti
12,351 Points

The for loop checking for student names matching the input is separate from the if statement checking for "quit" "all" or giving bad input error. Both the for loop's if statement and the second if statement send their results to the "message" variable. Since the code runs from top to bottom, the results will change as it trickles through the while loops. So... the program checks for an exact name, and if it matches one, then "message" will be loaded with the appropriate content. Then the if statement outside the for loop runs, and since the student name matched, it was neither quit, nor all... so both the if and else if clear, but that means the else runs, so: message = "Sorry, that student isn't in the database. Please try a different name." and is displayed. To verify this, and check for it in the future, add: console.log(message) after your first if statement, and it should display the correct output in the console but still return the sorry message.

Heather Scroggins
Heather Scroggins
30 Points

Okay, that makes total sense. I wasn't looking at it like that. So, I created a new variable, and assigned it it to take the place of the 'message' variables int he 'for' loop.....it's still not working. I have no idea what I'm doing wrong. The new code snippet is below. And I realize that even if I did type in a correct name the "Sorry, that name isn't in the database" message would appear below the student information, but I am going to figure that out later. I just want to get the 'for' loop working like it's supposed to be.

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

var searchResponse;
var message = '';
var allMessage = '';
var report = '';
var student;

while(true) {
  searchResponse = prompt("Welcome to the Student Search Engine(SSE). To find a student type the name below. To list all students in the SSE type 'all' (This will also exit the SSE). To exit the SSE type 'quit'.");
  searchResponse = searchResponse.toLowerCase();
  for (i = 0; i < students.length; i++) {
    student = students[i];
    if (student.name === searchResponse) {
      report = '<h2>Student: ' + student.name + '</h2>';
      report += '<p>Track: ' + student.track + '<br>';
      report += 'Achievements: ' + student.achievements + '<br>';
      report += 'Points: ' + student.points + '</p>';
      print(report);
    }
  }
  if (searchResponse === 'quit') {
    message = "Thank you for using the SSE.";
    print(message);
    break;
  } else if (searchResponse === 'all') {
    for (i = 0; i < students.length; i++) {
      allMessage += '<h2>Student: ' + students[i].name + '</h2>';
      allMessage += '<p>Track: ' + students[i].track + '<br>';
      allMessage += 'Achievements: ' + students[i].achievements + '<br>';
      allMessage += 'Points: ' + students[i].points + '</p>';
    }
    print(allMessage);
    break;
  } else {
    message = "Sorry, that student isn't in the database. Please try a different name.";
    print(message);
  }
} 
Allen Sutton
Allen Sutton
3,694 Points

Hi Heather,

I'll talk briefly about my thought process when addressing this one and hopefully it will help you out. First off, what is the SSE trying to do. Well it can search, list all or quit. So what might each one of those options entail?

First, search. Well, when searching we have to compare the name searched for and the names we have on file. Sounds like an if statement that'll print something if true. Cool.

Next, list all. Well, we're still printing out some information like with search but we don't care what the names are, we just want the info on the page. So we don't need to compare anything and can just print. Sounds like it could be a part of the same if statement as search somehow. So if it matches or if they want all, we need to print. Got it.

Last, quit. Well if the user wants to quit the SSE, do we really need to do anything other than quit? If we do, it just means we're making the program take longer to do what the user wanted. Break and be done.

So, we have sort of "outline" I guess you could call it.

  1. if the search matches a name, print the name
  2. if the user wants all the names, print all the names
  3. if the user wants to quit, quit

But how should we go about making this code? Well, it we try our best to keep in mind javascript, for the most part, runs from the top to the bottom, I think we can sort things that way. So currently the script will run just like the list: 1, 2 then 3. But is that order good? From thinking about what each option involves, it seems like "quit" needs the least work. it just, well, quits. The other two require quite a bit more code so lets just quit right off the bat if the users wants to. No need to do anything else. So our new order is like this:

  1. if the user wants to quit, quit
  2. if the search matches a name, print the name
  3. if the user wants all the names, print all the names

Ok, so looking at our other 2 options I'd say the "list all" option would need less work than the "search" option. We're not comparing anything and we don't care what names are were. We just want to print everything. So now we end up with:

  1. if the user wants to quit, quit
  2. if the user wants all the names, print all the names
  3. if the search matches a name, print the name

Well, now we just need to code it! To be brief since I've already written a novel, we need to grab the user input, check what that input was and then do something. I've ended up with this:

function printStudent(match) {

  message += '<h2>Student: ' + match.name + '</h2>';
  message += '<p>Track: ' + match.track + '</p>';
  message += '<p>Points: ' + match.points + '</p>';
  message += '<p>Achievements: ' + match.achievements + '</p>';

  print(message);

}

while (true) {

  search = prompt('name, all or quit');
  search = search.toLowerCase();

  if ( search === 'quit' ) break;

  var message = '';

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

    if (search === 'all' || search === student.name.toLowerCase())  {
      printStudent(student);
    }
  }

  if (search === 'all') {
    break;
  } else if (message === '') {
    print('<p>Sorry, No students found</p>');
  }

}

From the top, I set up a function to print out the names of the students to keep things clean. I figure we're going to be printing names after all so a function will help us quickly do so when we want. Then, we need our loop. In the loop, I grabbed the input from the user first, cause we can't really do anything without that. Next I see if the user wants to quit because we don't need to spend time doing anything other than quitting if the user wants to quit. If the loop doesn't break there, it will continue down the script. I set up a message var to store our student info we will be printing. Next on our list was the "list all." However, both "list all" and "searching" need to loop through all the students so we can just start looping and handle both in there. So as we loop, we want to print out the name if the user typed all. Well, we also want to print out the name if it matches. So we can see if one or the other is true. Once we finish looping through all the names, we can check if the the user had asked for all the names to be printed. If so, we want to break the while loop and be done looping cause there is nothing more to search for or loop through. Last, if the message var never had any students put into it by our function, then we didn't find any matches and can let the user know.

I left out a few of your messages just for clarity sake but the core of it is there and those bits are easily added. I'm no pro at this by any means so someone might have some corrections or insight on this but I hope that helped you out.

Cheers.