Contact Card Object Search

For the next part of the Object lesson we'll be creating objects in objects. I'll break down the code below. This code is the end result of the "Contact List" lesson; slightly adapted.

var friends = {};
friends.elmer = {
    firstName: "Elmer",
    lastName: "Fudd",
    number: "555-123-4567",
    address: ['12 Gauge Lane','Huntington','MA','02212']
};
friends.bugs = {
    firstName: "Bugs",
    lastName: "Bunny",
    number: "555-787-3687",
    address: ['1 Carrots Circle','Holebelow','NJ','07103']
};

var list = function(object) {
    for (var key in object) {
        console.log(key);
    }
};

var search = function(name) {
    for (var key in friends) {
        if (friends[key].firstName === name) {
            console.log("First Name: " + friends[key].firstName);
            console.log("Last Name: " + friends[key].lastName);
            console.log("Number: " + friends[key].number);
            console.log("Address: " + friends[key].address[0]);
            console.log(friends[key].address[1] + ", " + friends[key].address[2] + " " + friends[key].address[3]);
            //return friends[key];
        }
    }
};

//list(friends);
list(friends);
//search the friends list
search(prompt("Who's your friend?"));

We start off by creating an object called friends. It contains two keys, which also appear to be objects of their own.

var friend = {}; // list object, Object Literal Notation

friend.elmer = {}; //key 1, card object, Object Literal Notation
friend.bugs = {}; //key 2, card object, Object Literal Notation

Each card object then gets its keys, including an address line array.

friends.elmer = {
    firstName: "Elmer",
    lastName: "Fudd,"
    number: "555-123-4567",
    address: ['12 Gauge Lane','Huntington','MA','02212']
};

Detour : for/in loop

The basic for/in loop looks like this: for (var key in object) {};. What does this do? Key can be replaced by any other words you'd like to name your variable, but it represent the key in the object, so using key makes sense. The basic English version of this command is for each entry in the entity do the following. Since we're using an object with keys saying for each key in the object, do the following makes sense.

Okay, after some more research, here's a little extra. According to the experts at Mozilla the for...in loops over the enumerable properties of an object (specifically) in an arbitrary order (not necessarily in the specific order states in the object itself?).

This example is copied straight from the Mozilla page:

The following function takes as its argument an object. It then iterates over all the object's enumerable properties and returns a string of the property names and their values.

var obj = {a:1, b:2, c:3};

for (var prop in obj) {
    console.log("obj." + prop + " = " + obj[prop]);
}

// Output:
// "obj.a = 1"
// "obj.b = 2"
// "obj.c = 3"

Printing a list of contacts

Now we're creating a function that accepts the object as a parameter. It will go through the primary object (list) and for each key in the object print that key value to the console.

var list = function(object) {
    for (var key in object) {
        console.log(key);
    }
};

We use list(friends); to provide the "object" parameter and get elmer and bugs in return. If we changed "friends" to "friends.elmer" it would return firstName, lastName, number, address. This still confuses me. Here's a small experiment to see if I can make it behave like the Mozilla code. I'm changing the list function a little to:

var list = function(object) {
    for (var key in object) {
        console.log(object[key]);
    }
};

That format actually spits out the key values, not the key names. Makes sense now. Here's why: key = the key name, [key] = the key value. (key indicates position, [key] indicates the value at that position.)

Finding and Printing the Card

The next section runs the search function based on an input from the prompt at the end of the document.

var search = function(name) {
    for (var key in friends) {
        if (friends[key].firstName === name) {
            console.log("First Name: " + friends[key].firstName);
            console.log("Last Name: " + friends[key].lastName);
            console.log("Number: " + friends[key].number);
            console.log("Address: " + friends[key].address[0]);
            console.log(friends[key].address[1] + ", " + friends[key].address[2] + " " + friends[key].address[3]);
            //return friends[key];
        }
    }
};

The first thing we do is define the function here: var search = function(name) {}.

Then we create a for/in loop that loops through the friends object pulling each key. The if statement looks to see if the key we're currently looping by contains a key firstName and whether it matches the name we entered in the prompt. If it does we print out the rest of the card.

Making it all happen

Here we list all the contacts. If we made it a confirm we'd actually have this popup before the prompt is displayed. Or could we create prompt placholder text from this? (Quick experiment...) Nope, none of that worked. Keep it like it is.

list(friends);

Here we call the search function and get its parameter from a prompt (user input).

search(prompt("Who's your friend?"));