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

Miguel Pires
Miguel Pires
3,642 Points

If I type Jon, the var (notStudent is now false), but if I type another correct name it's always (true) why?

<script>
var search;
var studentNames;
var html ='';
var notStudent = true;
var students = [
    { name:'Jon', track:'Wordpress', achievements:12, points:1455 },
    { name:'Jon', track:'Javascript', achievements:9, points:1248 },
    { name:'Ron', track:'HTML', achievements:18, points:2208 },
    { name:'Rita', track:'JSon', achievements:6, points:799 },
  { name:'Isa', track:'AJAX', achievements:11, points:1397 },
  { name:'Jon', track:'UI/UX', achievements:2, points:144 }
];

function print (message) {
  var div = document.getElementById ('output');
  div.innerHTML = '<div>'+message+'</div>';
}

function list (student) {
   html +=('<h2>Student: '+student.name+'</h2>');
   html +=('<p>Track :'+student.track+'</p>');
   html +=('<p>Achievements: '+student.achievements+'</p>');
   html +=('<p>Points: '+student.points+'</p>');
   return html;  
}

while (true) {
  search = prompt ('search for students:');
    for (let i=0; i<students.length; i++) {
      studentNames = students[i];
      if (search === studentNames.name) {
        list(students[i]);
        print(html); 
        notStudent = false;
      } else { notStudent=true}
  } console.log(notStudent);
  if (search === 'quit' || search === '' || search === null) {
    notStudent = false;
    break;
  }
}
</script>

3 Answers

Hi Miguel

Ok so the reason is in your for loop

lets talk through it step by step

for students length (which is 6) if students name is equal to the search query set notStudent to false else set notStudent to true.

This means that it will go through all 6 objects in the array checking the search result, it will return true for some but not for all of them, so you received the correct result when you typed in Jon because Jon is the last in the loop to get checked therefore notStudent will be set to false.

When you typed in "Ron" in the loop the value of notStudent will go through the loop like so... true true false true true true

The easy way to fix this is add a break in your if statement, but there are better ways of dealing with conditionals in loops.

So, for example, this works fine:

I've added a console log in this, look what happens in the loop when you're looping through names, all i added was a break in your if statement

var search;
var studentNames;
var html = '';
var notStudent = true;
var students = [
    { name: 'Jon', track: 'Wordpress', achievements: 12, points: 1455 },
    { name: 'Jon', track: 'Javascript', achievements: 9, points: 1248 },
    { name: 'Ron', track: 'HTML', achievements: 18, points: 2208 },
    { name: 'Rita', track: 'JSon', achievements: 6, points: 799 },
    { name: 'Isa', track: 'AJAX', achievements: 11, points: 1397 },
    { name: 'Jon', track: 'UI/UX', achievements: 2, points: 144 }
];

function print(message) {
    var div = document.getElementById('output');
    div.innerHTML = '<div>' + message + '</div>';
}

function list(student) {
    html += ('<h2>Student: ' + student.name + '</h2>');
    html += ('<p>Track :' + student.track + '</p>');
    html += ('<p>Achievements: ' + student.achievements + '</p>');
    html += ('<p>Points: ' + student.points + '</p>');
    return html;
}

while (true) {
    search = prompt('search for students:');
    for (let i = 0; i < students.length; i++) {
        studentNames = students[i];
        console.log(students[i].name);
        if (search === studentNames.name) {
            list(students[i]);
            print(html);
            notStudent = false;
            break;
        } else { 
            notStudent = true;
         }
    } console.log(notStudent);
    if (search === 'quit' || search === '' || search === null) {
        notStudent = false;
        break;
    }
}
Miguel Pires
Miguel Pires
3,642 Points

Really apreciated your answer, thanks for your time. I understood what you mean. I have more 2 questions: 1 - I think the break just stopped the for loop and not the while loop, so prompt continue to appear, that's right? 2 - Now with the break it doesn't run all the array, so it just print one object with the same name. How can I fix this? My first thought was to put all the match names in a new array and print it, but when I do it inside the for loop, even without break it just add me one object with the same name.

Thanks again Liam :)

  1. Yes you are correct, for and while are both loops and the break will just come out of the direct loop it is in.

  2. There are a bunch of different ways you can fix this, one way which is probably the most straight forward way is to have a separate function for the notStudent variable that only gets invoked when the condition is met.

its considered good practice to have a function that logically does one thing, so maybe something like this:

var search;
var studentNames;
var html = '';
var notStudent = true;
var students = [
    { name: 'Jon', track: 'Wordpress', achievements: 12, points: 1455 },
    { name: 'Jon', track: 'Javascript', achievements: 9, points: 1248 },
    { name: 'Ron', track: 'HTML', achievements: 18, points: 2208 },
    { name: 'Rita', track: 'JSon', achievements: 6, points: 799 },
    { name: 'Isa', track: 'AJAX', achievements: 11, points: 1397 },
    { name: 'Jon', track: 'UI/UX', achievements: 2, points: 144 }
];

function print(message) {
    var div = document.getElementById('output');
    div.innerHTML = '<div>' + message + '</div>';
}

function list(student) {
    let html = ('<h2>Student: ' + student.name + '</h2>');
    html += ('<p>Track :' + student.track + '</p>');
    html += ('<p>Achievements: ' + student.achievements + '</p>');
    html += ('<p>Points: ' + student.points + '</p>');
    return html;
}

function isStudent() {
    notStudent = false;
}

while (true) {
    notStudent = true;
    search = prompt('search for students:');

    for (let i = 0; i < students.length; i++) {
        if (search === students[i].name) {
            html += list(students[i]);
            print(html);
            isStudent();
        }
    }

    if (search === 'quit' || search === '' || search === null || notStudent === false) {
        break;
    }
}

There is still a fair amount of improvement to this code but let's keep it focussed on your question, does this do what you expect?

When you search a correct name, it will show all the search results, if you search an incorrect name it will just open the prompt again

Miguel Pires
Miguel Pires
3,642 Points

Yes it's just right! So simple. I understood what you've done by putting notStudent = true; at the while loop, and not inside the for loop. This way if it matches the condition it will put notStudent = false; from the object where it matches to the end of the array.

Thanks again for your help Liam.