Help With Looking Up Object Properties Nested Within An Array

Profile Lookup challenge within Basic JavaScript

So here is the challenge that I am stuck on. Any help and advice to get me to solve it will be appreciated.

Challenge Directions:

We have an array of objects representing different people in our contacts lists.

A lookUpProfile function that takes firstName and a property (prop) as arguments has been pre-written for you.

The function should check if firstName is an actual contact’s firstName and the given property (prop) is a property of that contact.

If both are true, then return the “value” of that property.

If firstName does not correspond to any contacts then return “No such contact”

If prop does not correspond to any valid properties then return “No such property”

//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(firstName, prop){
// Only change code below this line

    if (contacts.firstName === true && contacts.hasOwnProperty(prop) === true) {
    return contacts[prop];
  } else if (contacts.firstName !== true) {
    return "No such contact";
  } else (contacts.hasOwnProperty(prop !== true)); {
    return "No such property";
  }

// Only change code above this line
}

// Change these values to test your function
lookUpProfile("Akira", "likes");

Before this challenge came up I was going through arrays with for and while loops. I say this because it is probably related, but I am not sure how to tie that into this challenge, if I need to.

What I really need help with is understanding how to access the property of an object nested within an array. Maybe I am more lost than that, but I appreciate any help on this.

Using a for loop to go through an array of objects is a good plan. Here’s part of your code integrated into a for loop to get you started:

  for (var i = 0; i < contacts.length; i++) {
    if (contacts[i].firstName === firstName) {
      return contacts[i].firstName; //this is just an example
    }
  }

See if you can work it out now. The tricky part is knowing when to return and ensuring that you don’t return too early.

It will help to check if firstName is an actual contact’s firstName, and then check if the given property (prop) is a property of that contact rather than checking them both at the same time.

1 Like

How do I check to see if the prop argument is a property within one of the objects? The only thing that I can think of is to use the .hasOwnProperty method. My code right now looks like this:

function lookUpProfile(firstName, prop){
// Only change code below this line
  for (i = 0; i < contacts.length; i++) {
    if (contacts[i].firstName === firstName) {
      if (contacts[i].hasOwnProperty(prop) === true) {
        return contacts[i].prop;
      }
    }
  }
// Only change code above this line
}

This doesn’t seem right though because I am not accessing the object directly, and so I don’t know how to return the value of the prop argument if it is true. I appreciate your advice in helping me solve this.

Try if Firstname exist, do another for loop to access object property.
Example contact[i][x].

Is a great exercise to practise for loops inside objects, you have a similar exercise in Codecademy Javascript.

1 Like

This is good. Personally I would combine your if statements to one line like:

if (contacts[i]["firstName"] === firstName && contacts[i].hasOwnProperty(prop) ) {
    return contacts[i][prop];
}

But that should work fine. And then you just have to handle the case where nothing has been returned yet and youre golden.

1 Like

Just a tiny change from contacts[i].prop to contacts[i][prop]. So your code should look like this now:

  for (i = 0; i < contacts.length; i++) {
    if (contacts[i].firstName === firstName) {
      if (contacts[i].hasOwnProperty(prop) === true) {
        return contacts[i][prop];
      }
    }
  }
1 Like

Ok I am really close to getting it. Things fell apart though once I put in the else statement. The first part that we have been discussing runs fine without the else statement. Once the else comes in then the first if statement stops passing, and it only checks the else statement, but when I remove the else it will run fine again. Does my else statement need to be outside of the loop?

function lookUpProfile(firstName, prop){
// Only change code below this line
  for (i = 0; i < contacts.length; i++) {
    if (contacts[i].firstName === firstName && contacts[i].hasOwnProperty(prop)) {
      return contacts[i][prop];
    } else if (contacts[i].firstName !== firstName && contacts[i].hasOwnProperty(prop)) {
      return "No such contact";
    } else {
      return "No such property";
    }
  }
// Only change code above this line
}

Or do I need another for loop before I run my else if statement?

Everything is passing now except the else if statement which is supposed to return “No such contact”. The first if statement passes, and the last else statement passes.

function lookUpProfile(firstName, prop){
// Only change code below this line
  for (i = 0; i < contacts.length; i++) {
    if (contacts[i].firstName === firstName && contacts[i].hasOwnProperty(prop)) {
      return contacts[i][prop];
    } else if (contacts[i].firstName !== firstName && contacts[i].hasOwnProperty(prop)) {
      for (j = 0; j < contacts[j].length; j++) {
        return "No such contact";
      }
    } else {
      return "No such property";
    }
  }
// Only change code above this line
}

Thanks for all your help everyone. I figured it out.

function lookUpProfile(firstName, prop){
// Only change code below this line
  for (i = 0; i < contacts.length; i++) {
    if (contacts[i].firstName === firstName && contacts[i].hasOwnProperty(prop)) {
      return contacts[i][prop];
    }
  }
  
  for (i = 0; i < contacts.length; i++) {
    if (contacts[i].firstName !== firstName && contacts[i].hasOwnProperty(prop)) {
      return "No such contact";
    }
  }
  
  for (i = 0; i < contacts.length; i++) {
    if (contacts[i].firstName === firstName && contacts[i].hasOwnProperty(prop) !== true) {
      return "No such property";
    }
  }
  
// Only change code above this line
}

Good job man.

Not to steal your thunder, but you really don’t need more than one loop. Something like:

function(firstName, prop) {
    for (i = 0; i < contacts.length; i++) {
        if (contacts[i].firstName === firstName && contacts[i].hasOwnProperty(prop)) {
            return contacts[i][prop];
        }
    }
    return "No such property";
}

`
is a bit more efficient.

Yeah that makes a lot of sense. I was trying to use else if statements and it wasn’t working for me. Also, I needed to have a few different returned strings, so how would you have returned “No such contact”. Right now with what you posted it either returns the property value, or it returns no such property. How would you get it to return something if the property is true, and the name is false the way that you did it?

I undeleted my previous posts which will show you what I was trying earlier, but wasn’t working. If you could help me understand what was happening with that code that would be great.

Oops look like I misread the function requirements. Hopefully I didn’t mislead you. What you need is:

function(firstName, prop) {
    for (i = 0; i < contacts.length; i++) {
        if (contacts[i].firstName === firstName) {
            return  contacts[i].hasOwnProperty(prop) ? contacts[i][prop] : "No such property";
        }
    }
    return "No such contact";
}

This syntax might be simpler to understand:

function(firstName, prop) {
for (i = 0; i < contacts.length; i++) {
    if (contacts[i].firstName === firstName) {
        if( contacts[i].hasOwnProperty(prop) ) {
            return contacts[i][prop];
        }
        else {
            return "No such property";
        }
    }
}
return "No such contact";

}

Awesome, I get that now. Could you explain this line for me.

return  contacts[i].hasOwnProperty(prop) ? contacts[i][prop] : "No such property";

I havn’t seen this with the ? in there before.

it is shorthand for if, else. I believe it is called ternary operator or something. Basically just a fancy if else statement that lets you write less code sometimes.

The solution:

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

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

// Only change code above this line
}

// Change these values to test your function
lookUpProfile(“Akira”, “likes”);