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

What is wrong with my code/logic ?

Hi, i'm trying to do the Bonus Challenge (first part)

When i run the code, even if the name typed is inside the students array, the content of my "for" loop doesn't seem to work because i get the message " There is no student ..." except for Trish (i don't know why). Could you please explain to me where i got lost ?

var students = [ 
  { 
    name: 'Dave',
    track: 'Front End Development',
    achievements: '158',
    points: '14730'
  },
  {
    name: 'Jody',
    track: 'iOS Development with Swift',
    achievements: '175',
    points: '16375'
  },
  {
    name: 'Jordan',
    track: 'PHP Development',
    achievements: '55',
    points: '2025'
  },
  {
    name: 'Jody',
    track: 'Learn WordPress',
    achievements: '40',
    points: '1950'
  },
  {
    name: 'Trish',
    track: 'Rails Development',
    achievements: '5',
    points: '350'
  }
];


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

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

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) {
  search = prompt ('Please type a student name');

  if (search === null || search.toLowerCase() === 'quit') {
    break;
  }

  for (i = 0; i < students.length; i += 1) {
    student = students[i];
    if (student.name === search) {
     message = getStudentReport(student);
     print(message);
    }

    else {
      message = "<p> There is no student with the name " + search  + "</p>";
      print(message);
    }
  }
}
Karolin Rafalski
Karolin Rafalski
11,368 Points

can you also show the code for your student array?

3 Answers

Karolin Rafalski
Karolin Rafalski
11,368 Points

Without the break statement, there is only one way out of the for statement. That is when i < students.length; is no longer true.

Whether or not the if statement is true, it has no effect on the for loop - unless you add a break.

If this still tough to visualize, I would recommend writing FizzBuzz:

From http://eloquentjavascript.net/02_program_structure.html

FizzBuzz

Write a program that uses console.log to print all the numbers from 1 to 100, with two exceptions. For numbers divisible by 3, print "Fizz" instead of the number, and for numbers divisible by 5 (and not 3), print "Buzz" instead.

When you have that working, modify your program to print "FizzBuzz", for numbers that are divisible by both 3 and 5 (and still print "Fizz" or "Buzz" for numbers divisible by only one of those).

(This is actually an interview question that has been claimed to weed out a significant percentage of programmer candidates. So if you solved it, you’re now allowed to feel good about yourself.)

Ok, i finally get it. Thx a lot Karolin

Steven Parker
Steven Parker
231,269 Points

You have an "if...else" inside a loop, and both use the print function which replaces the contents of the element with id "output". This means that "output" is overwritten for every student, so only the result of the last test (for "Trish") will be seen. So if the search is for "Trish", you get the stats, and if the search is for anything else (valid or not) you get the "not found" message.

One way to handle this is add a "break" inside the if block to stop iteration when the search is found. Then remove the "else" and move the associated code to after the loop into a new test. The new test will check if the loop index went to students.length, indicating that nothing was found.

It might look something like this:

  var i;  // define i now for testing later
  for (i = 0; i < students.length; i += 1) {
    student = students[i];
    if (student.name == search) {
      print(getStudentReport(student));
      break;
    }
  }
  if (i >= students.length) {
    print("<p> There is no student with the name " + search + "</p>");
  }

I don't get why the print function is overwritten if the "if statement" is true. By adding a "break" after the "if statement", the code works but i don't understand why i need to add this break.

I added comments to my code to explain better my logic, what did i missunderstood ?

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

//Creating a function to print the result inside the output div
function print(message) {
  var outputDiv = document.getElementById('output');
  outputDiv.innerHTML = message;
}

//Creating a function to return data from student
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;
}

/*Creating a undless loop (=> "while(true)"  is always true)
to show a prompt dialog box that ends only 
 if we click on "cancel" (search value will be equal to "null") or 
 if we type "quit" (search value will be equal to "quit")
*/
while(true) {
  search = prompt('Please type a student name');
  if (search === null || search.toLowerCase() === 'quit') {
    break;
  }

  /*
Creating a loop inside a loop  to browse the array
We give the "student" variable a value which is equal to each object in the students array
We check if what we type in the prompt dialog box matches with the name parameter of each object
 => If the search is equal to the name of the student, then we get  all the data of the student (put in the message variable), then print the content of the message variable.
 => Otherwise, we change the content of the message variable to show "There is no student with the name ..."
then print the content of the message variable.
*/
  for (i = 0; i < students.length; i += 1) {
    student = students[i];
    if (student.name === search) {
     message = getStudentReport(student);
     print(message);
    }
    else {
      message = "<p> There is no student with the name " + search  + "</p>";
      print (message);
    }
  }
}
jamaleh gyulay
jamaleh gyulay
1,794 Points

axel ^ I'm wondering if its better to take the else statement out of the loop. I noticed that it is printing the message for each student object.

Yes indeed, we need to get out of the loop and end the iteration when a student is found to print the student's stats.

That can be done (among others) by removing the "else" statement out of the loop or adding a "break" after the "if" statement.´

while (true) {
  search = prompt ('Please type a student name');

  if (search === null || search.toLowerCase() === 'quit') {
    break;
  }

  else {
    message = "<p> There is no student with the name " + search  + "</p>";
    print(message);
  }

  for (i = 0; i < students.length; i += 1) {
    student = students[i];
    if (student.name === search) {
     message = getStudentReport(student);
     print(message);
    }
  }
}

or

while (true) {
  search = prompt ('Please type a student name');

  if (search === null || search.toLowerCase() === 'quit') {
    break;
  }

  for (i = 0; i < students.length; i += 1) {
    student = students[i];
    if (student.name === search) {
     message = getStudentReport(student);
     print(message);
     break;
    }

    else {
      message = "<p> There is no student with the name " + search  + "</p>";
      print(message);
    }
  }
}

Yet, i don't know what is best practice ? I know there are other solutions but between these ones ?

For both, reseting the value for the message variable may be unnecessary and redundant ? ? so could be changed by :

while (true) {
  search = prompt ('Please type a student name');

  if (search === null || search.toLowerCase() === 'quit') {
    break;
  }

  else {
   print( "<p> There is no student with the name " + search  + "</p>");
  }

  for (i = 0; i < students.length; i += 1) {
    student = students[i];
    if (student.name === search) {
     message = getStudentReport(student);
     print(message);
    }
  }
}