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

Konstantinos Pedarakis
Konstantinos Pedarakis
21,301 Points

My solution of final challenge (with more clean code). Feel free to add any feedback or thoughts to improve it.

This is my final challenge code. Tried to organize things a bit. i provided some comments to explain the code as good as i possibly could. Any feedback is much appreciated. Hope that helps newcomers :) Happy coding.

var students = [
  {
    name: "John",
    Track: ["Web development", "HTML", "CSS", "PHP", "C#"],
    Achievements: 100,
    Points: 8000
  },
  {
    name: "George",
    Track: ["Android", "HTML", "CSS"],
    Achievements: 20,
    Points: 3500
  },
  {
    name: "Jim",
    Track: ["Web development", "HTML", "CSS", "Ruby", "C#"],
    Achievements: 150,
    Points: 7500
  },
  {
    name: "Peter",
    Track: ["Software development"],
    Achievements: 250,
    Points: 10000
  },
  {
    name: "Alex",
    Track: ["HTML", "CSS", "Java", "Asp.net"],
    Achievements: 50,
    Points: 100
  },
  {
    name: "Peter",
    Track: ["HTML", "CSS", "Java", "Asp.net"],
    Achievements: 50,
    Points: 100
  }
];
var foundStudent = [];
var HTMLMessage= "";
function print(message) {
  document.getElementById("output").innerHTML = message;
}
//function that capitalize the first lettet of the input
function capitalize(string) {
  return string.charAt(0).toUpperCase() + string.substring(1);
}
//printReport generates the HTML message when we pass
//the object from the array that we store the students that are exist.
//a for in loop of the object displays the names of the properties
//instead of typing them in the markup.
function printReport(obj) {
  HTMLMessage += "<h2>" + obj.name + "'s Record</h2>";
  for (prop in obj) {
    HTMLMessage += "<p>" + prop + " : " + obj[prop] + "</p>";
  }
  return HTMLMessage;
}
//start of the program
//while loop that asks for a user input and converts the input in lowercase.(we dont concern about the first letter because we have
// our capitalize function.)
while (userInput != "quit") {
  var userInput = prompt("Please enter a student's name.").toLowerCase();
//we are looping in students array to compare if there is a match comparing the userInput with students array.
//if there is a match however, we store that student in another array called foundStudent.
  for (var i = 0; i < students.length; i++) {
      if (capitalize(userInput) === students[i].name) {
        foundStudent.push(students[i]);
      }
    }
    //we are still inside the while loop, so here, if the foundStudent length is 0, meaning that is empty,
    //and if the user didn type "quit", then we are telling that the student is no found.
    if (foundStudent.length === 0 && userInput != "quit") {
      print("Student with the name " + userInput + " not found.");
    } else {
      //else meaning that if the foundStudent array has something in it, then we looping through this array,
      //and passing the object to the printReport function to generate our HTML and print it.
      for (var i = 0; i < foundStudent.length; i++) {
        print(printReport(foundStudent[i]));
      }
      //after we have done with the looping and printing we reset the HTML message because we dont want,
      // previous results to be printed in our page and we empty the foundStudent array.
      HTMLMessage = "";
      foundStudent = [];
    }
}

2 Answers

So, a few comments...

First, the variable name HTMLMessage isn't so good, since the convention/standard is to only use variable names beginning with capitals for classes of objects. Stick to camelCase:

var htmlMessage = "";
// or even without the HTML part, since it can have the same name as the parameter in the print function
var message = "";

Second, you could be limiting the results returned (if this were a bigger dataset) by using the capitalize function to compare the user's input to the names. You could instead make both the user input and the name being compared lower case, just within the conditional (it won't change the actual value of the variable):

// remove the '.toLowerCase' from the variable
  var userInput = prompt("Please enter a student's name.");
// ...
  for (var i = 0; i < students.length; i++) {
      if (userInput.toLowerCase() === students[i].name.toLowerCase()) {
        foundStudent.push(students[i]);
      }
    }

Third, you're not telling the user how they can quit with the prompt, so unless they view your code first, they wouldn't know.

  var userInput = prompt("Please enter a student's name or type 'quit' to stop.").toLowerCase();

Fourth, if the user hits OK without entering anything, they will see the message: Student with the name not found. printed in the HTML. You might want to instead check for an empty string and handle that case. For example, you could just continue the loop (show the prompt again):

// at the top of the while loop, after showing the prompt:
if (userInput === "") {
  continue;
}

Fifth, if the user hits ESC on their keyboard or presses the Cancel button, you get an error in the console, because userInput will be equal to null. You might want to set userInput to quit in that case so the while loop finishes, and perhaps print a helpful/nice message for the user:

// at the top of the while loop, after showing the prompt, probably before checking for an empty string or anything else:
if (userInput === null) {
  print("Goodbye!");
  userInput = "quit";
  continue;
}

You could alternatively change the while loop to be an infinite one, but check to see if the user cancelled or typed 'quit' from within the loop and break from the loop:

while (true) {
  var userInput = prompt("Please enter a student's name or type 'quit' to stop.");
  if (userInput === null || userInput.toLowerCase() === "quit") {
    print("Goodbye!");
    break;
  }

Here's a JS Bin of the code with my suggestions/modifications: http://jsbin.com/jifaro/1/edit?html,js,console,output

Konstantinos Pedarakis
Konstantinos Pedarakis
21,301 Points

Iain Simmons First of all thank you very much for taking the time to see my code and make additional comments. Everything that you said are extremely helpful. Some things i want to mention. On your first comment about the HtmlMessage, yeah i don't know why i left it as it is, probably i forgot it, the thing is that i get the rule of CameCase so this is not an excuse. Next, sure i could add the condition for the empty string by continuing the loop, i didn't cause i just want stick to the exercise, i mean, you could whatever you want right? the sky is the limit! And sure i could add a condition for the esc button to print a Goodbye message as you very well did. i totally missed that part. Thanks again for your feedback, i really appreciate that you seperate the code in small sections and analyze them seperately.

No problem! :)