Lesson Wednesday

Our address book is great at keeping track of our contacts' names, but it is conspicuously missing any actual addresses. We want to be able to add multiple Address objects to each of our Contact objects, since a user may have a personal address, a business address, a shipping address, etc that are all different.

Before returning to our code, let's jump back to the JavaScript console for a bit to practice inserting Address objects into Contact objects.

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 a lastName, but also to contain an array of Address objects. So when we first create each Contact object, let's initialize it with an empty addresses array:

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

We will still create Contact objects in exactly the same way:

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

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

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

Note that we did not pass in an empty array when we constructed our lisa object. We can run whatever code and initialize whatever properties we want inside of our constructor. In this case we know that every Contact object should have an addresses property that starts out as an empty array. Since we're initializing it to the same value every time we create a new contact, there is no reason to require the user interface logic to pass in an empty array every time. We just automatically create an addresses property in the constructor 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 that is created.

We follow the same process we used when we created our Contact constructor. When our Address constructor is called to construct a new Address object, it will receive parameters for a street, city and state. It should set corresponding street, city and state properties on the Address object it's creating.

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

Let's try putting all this business logic together in the JavaScript console.

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; }

Now create a Contact object and an Address object:

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

Let's check that these two objects have been instantiated (created) correctly:

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

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

Great. Now time to combine them by adding this Address object to our Contact object's addresses array property:

> lisa.addresses.push(home);

And check to make sure our lisa Contact object's addresses array does indeed contain an element now:

> 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:

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

And sure enough it looks to contain an Address object (an instance of the Address type), containing the correct info. Now if we needed to access the individual elements of the address we could do so as follows:

> 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 just as we could before:

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

Now let's incorporate this into our address book page.

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 = [];
}

And add our Address constructor:

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

Let's go ahead and make a commit at this point before we move on to the accompanying user interface logic.

GitHub addressBook repo at this point

Sample code (Address constructor & updated Contact constructor only):

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;
}