Profile Lookup - If statements tripping over each other

Tell us what’s happening:

Two posts in one day… Oh, dear. I’ve been able to get the first three parts of this challenge ticked off, however, when I then tackled the next step in the process, the first three ticks reverted to crosses, and parts 4 & 5 then became successful. I’m unsure why my ‘if’ statements appear to be tripping each other up. I’ve screen grabbed below to make this clearer:

When I add my next ‘if’ rule, I get this:

As with all issues, I’m sure it’s simple, but I’m even simpler :frowning:

Your code so far


//Setup
var contacts = [
    {
        "firstName": "Akira",
        "lastName": "Laine",
        "number": "0543236543",
        "likes": ["Pizza", "Coding", "Brownie Points"]
    },
    {
        "firstName": "Harry",
        "lastName": "Potter",
        "number": "0994372684",
        "likes": ["Hogwarts", "Magic", "Hagrid"]
    },
    {
        "firstName": "Sherlock",
        "lastName": "Holmes",
        "number": "0487345643",
        "likes": ["Intriguing Cases", "Violin"]
    },
    {
        "firstName": "Kristian",
        "lastName": "Vos",
        "number": "unknown",
        "likes": ["JavaScript", "Gaming", "Foxes"]
    }
];


function lookUpProfile(name, prop){
// Only change code below this line

for (var x = 0; x < contacts.length; x++) {
    if (contacts[x].firstName === name && contacts[x].hasOwnProperty("lastName")) {
        return contacts[x][prop];
    } if (contacts[x].firstName !== name) {
        return "No such contact";
    }
}

// Only change code above this line
}

// Change these values to test your function
lookUpProfile("Kristian", "lastName");


Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:67.0) Gecko/20100101 Firefox/67.0.

Link to the challenge:

So, your function call is lookUpProfile("Harry", "likes")
the function starts the loop, the first item in the loop is the one about Akira… so let’s check… this is true: contacts[x].firstName !== name, so the body of the if statement is executed: return "No such contact";, and it’s the wrong output because Harry exist in the contact object.

Do you get what is the error?

Now that I look at it again, I’m confused as to why lookUpProfile("Harry", "likes") is giving the wrong result for lookUpProfile("Kristian", "lastName"). Based on the following:

 if (contacts[x].firstName === name && contacts[x].hasOwnProperty("lastName")) {
        return contacts[x][prop];

Shouldn’t that come first in the ‘if’ loop? Both conditions would be true, so I’m not sure why that test is failing when I add contacts[x].firstName !== name into the mix.

Because you have a return statement that runs as soon as contact[x].firstName !== name is true
The first iteration of the loop contact[0].firstName is "Akira", so, because name is not "Akira" that if statement is triggered and the return statement is executed

Are you sure you want that return statement there?

I feel bad for asking (what is most likely) stupid questions!

I get there is a return statement after contact[x].firstName !==, but there is also a return statement after
if (contacts[x].firstName === name && contacts[x].hasOwnProperty(prop)) {
return contacts[x][prop];

I’m not understand why the second return statement is being returned first.

At first iteration of the loop, x is 0 so the object at contact[0] is checked.
This object is

  {
        "firstName": "Akira",
        "lastName": "Laine",
        "number": "0543236543",
        "likes": ["Pizza", "Coding", "Brownie Points"]
    }

This object trigger the second return statement, because the firstName is different from name

As such, the other objects in the array are never checked because a return statement breaks from the function.

Harry would be checked at x with value of 1 and Kristian at 3, but the loop never arrive there because a return statement has already been executed

1 Like

They are two different function calls, both have the same issue, but are different function calls, one would not interfere with the other

I think I’ve understood what you’re saying. I’ve made a small change to one part of the code, as I realise it should be checking for contacts[x].hasOwnProperty(prop)) instead of having “lastName” in hasOwnProperty. So, with inputs of “Harry” and “likes”, it gets to the first part of the contacts list, and runs the following:

if (contacts[x].firstName === name && contacts[x].hasOwnProperty(prop)) { return contacts[x][prop];

It checks the first condition against "firstName" : "Akira", which is return as false. Akira does not equal Harry. With that as false, it then goes to the next if:

if (contacts[x].firstName !== name) { return "No such contact";

It checks the condition against "firstName" : "Akira", which it also return as false, because Akira does not equal Harry, therefore it returns “No such contact.”

I see where I was going wrong. I was thinking it would cycle the first if through the entire contacts list before moving on to the second if. I’n not sure where I got that idea from.

So, assuming I’ve understood this correctly, I’m guessing this will require multiple else if conditions?

Less than you think. You need if/else and/or nested if because there is also the “No such property” thing

But to check if the contact exist or not you need to do an other thing.
Think, when you would say for sure that the code has not found the required contact? ("Bob" in this case)
You reasoning was correct, but you were applying it to a wrong interpretation of how Code works

In order to be sure, then I would need contacts[x].firstName === name && contacts[x].hasOwnProperty(prop) to cycle through the entire contacts list before moving on to any other if statements. I’m trying to get this through nesting at the moment.

I don’t think you can do it trough nesting… as you said, there is a before and after involved

I’ve made progress, but there is one part that is still returning the wrong result:


 for (var x = 0; x < contacts.length; x++) {
    if (contacts[x].firstName === name && contacts[x].hasOwnProperty(prop)) {
        return contacts[x][prop];
    } else if (contacts[x].hasOwnProperty(prop) == false) {
        return "No such property";
    }
} return "No such contact"; 

When I run "Bob", "Number" I get a result of “No such contact”, which is correct. However, "Bob", "Potato" isn’t returning the same result. I can’t see why this is, as they look like the same thing to me. I can’t see why these aren’t both covered by the first if, as they should both fail at the point where it sees that Bob does not exist within the contacts list.

It is because your if else statement is checking only if the user does not have the right property, indipendently from what firstName is

That is a reason why I was talking about nested if else statement, so you check first if it is the right name, and inside it the prop

I’m not sure I follow you. I don’t see how lines 4 & 5 in the below image are different.

Line 4 is “Bob”, “number”. It runs (contacts[x].firstName === name && contacts[x].hasOwnProperty(prop)). The first condition is not met, so it returns “No such contact.”

Line 5 is "Bob, “potato”. It runs (contacts[x].firstName === name && contacts[x].hasOwnProperty(prop)) again. The first condition is not met, so I don’t see why it doesn’t jump to the same return as above.

I think I get it. It’s because it doesn’t skip to the end, it skips to the next part of the if section, which is my else if part. Back to the drawing board…

1 Like

It sure isn’t pretty, but it worked:

for (var x = 0; x < contacts.length; x++) {
    if (contacts[x].firstName === name && contacts[x].hasOwnProperty(prop)) {
        return contacts[x][prop];
    } else if (contacts[x].firstName === name && contacts[x].hasOwnProperty(prop) == false) {
        return "No such property";
    }
} return "No such contact";

Thanks for your patience with this. I feel like I understand the if logic a lot better now!

You could make it prettier creating nested if statements
With pseudocode:

IF the name match DO:
         IF there is the prop DO
                 return the prop value
         END IF
         ELSE DO
                 "No such property"
         END ELSE
END IF