Lesson Monday

Our address book is great at keeping track of our contacts' full names; but conspicuously enough, it's missing any actual addresses! Let's add this functionality now.

If you think about it, addresses have properties of their own. They have a street, a city, a state, and a zip code. Because every address will have these same properties, let's create Address objects. Then, we'll associate these Address objects with the Contact object to which the address belongs. When we're done, we'll have a Contact object with an addresses property. This addresses property will be an array that eventually contains multipleAddress objects.

In our app, we want to associate multiple Address objects to each of our Contact objects, since a user may have a personal address, a work or business address, a mailing address, etc. that are all different.

Before returning to our project, let's experiment insertingAddress objects into Contact objects in the JavaScript console.

Business Logic - Contact & Address Constructors

Previously we defined our Contact constructor like this:

function Contact(first, last) {
  this.firstName = first;
  this.lastName = last;
}

But now we want each Contact to contain not only a firstName and lastName, but an array of Address objects too. When we first create a new Contact, this array will start out empty. Then, when the user provides addresses for the particular Contact, we will create a new Address out of each, and push it to that Contact's addresses array.

To do this we'll need to ensure each new Contact is initialized with an empty addresses array. We'll add the following to the Contact constructor:

function Contact(first, last) {
  this.firstName = first;
  this.lastName = last;
  this.addresses = [];
}

Now, we will still create Contact objects the exact same way as before:

> var lisa = new Contact("Lisa", "Simpson");

But now if we look at our lisa object, we'll see that it now includes an empty addresses array:

> lisa
Contact {firstName: "Lisa", lastName: "Simpson", addresses: Array[0]}

You may have noticed we did not pass in an empty array as an argument when we created our lisa object in the line var lisa = new Contact("Lisa", "Simpson");. Since we're defining the addresses property as the same thing every single time we create a new Contact, there is no reason to require an empty array as an argument. Instead, it's much more efficient to have our constructor automatically create an addresses property and assign it to be an empty array.

Now we need to write an Address constructor. At a minimum each Address object will need to know its own street, city, and state. We can create an Address constructor that will add each of those properties to every Address object created.

This should look fairly similar to our Contact constructor. When our Address constructor is called to create a new Address object, we will provide it parameters for a street, city and state. It will then set corresponding street, city and state properties on the Address object it's creating as equivalent to the arguments that were passed in.

function Address(street, city, state) {
  this.street = street;
  this.city = city;
  this.state = state;
}

Let's put this together in the JavaScript console.

First, we'll create our two constructors:

> function Contact(first, last) { this.firstName = first; this.lastName = last; this.addresses = []; }
> function Address(street, city, state) { this.street = street; this.city = city; this.state = state; }

Next, we'll create a Contact object and an Address object:

> var lisa = new Contact("Lisa", "Simpson");
> var home = new Address("742 Evergreen Terrace", "Springfield", "Oregon");

Then, let's double-check that these objects have been created correctly:

> lisa
Contact {firstName: "Lisa", lastName: "Simpson", addresses: Array[0]}

> home
Address {street: "742 Evergreen Terrace", city: "Springfield", state: "Oregon"}

Looks good! Now, let's associate this particular Address with the Contact we've just created by adding the Address object to our Contact object's addresses property:

> lisa.addresses.push(home);

Finally, we'll check that our lisa Contact object's addresses array does indeed contain an object:

> lisa
Contact {firstName: "Lisa", lastName: "Simpson", addresses: Array[1]}

We can see that lisa's addresses array does now contain 1 element. Just to be sure it all worked, we can look and see the contents of that first array element, too:

> lisa.addresses[0]
Address {street: "742 Evergreen Terrace", city: "Springfield", state: "Oregon"}

And sure enough it contains an Address object with the correct information. Now, if we needed to access the individual elements of the address we could do the following:

> lisa.addresses[0].street
"742 Evergreen Terrace"
> lisa.addresses[0].city
"Springfield"
> lisa.addresses[0].state
"Oregon"

And of course we can still access lisa's other properties the same as we've done previously:

> lisa.firstName
"Lisa"
> lisa.lastName
"Simpson"

Now that we've seen how this works, let's incorporate it into our address book application.

First, we'll update our Contact constructor to initialize all Contact objects with an empty addresses array property:

js/scripts.js
function Contact(first, last) {
  this.firstName = first;
  this.lastName = last;
  this.addresses = [];
}

Next, we'll add our new Address constructor:

js/scripts.js
function Address(street, city, state) {
  this.street = street;
  this.city = city;
  this.state = state;
}

Awesome! In upcoming lessons we'll update the user interface logic to support our new Address feature.


Example GitHub addressBook Repo at this point

Examples


The following changes are made to our ongoing Address Book application in this lesson:

js/scripts.js
function Contact(first, last) {
  this.firstName = first;
  this.lastName = last;
  this.addresses = [];
}

function Address(street, city, state) {
  this.street = street;
  this.city = city;
  this.state = state;
}
  1. We add an addresses property to our Contact constructor. This is an array that will eventually contain Address objects.
  2. We create an Address constructor that will instantiate Address objects, which will eventually be pushed into the Contact's addresses array.