Lesson 2
Creating a Simple Address Book Application Using JavaScript Maps
Introduction

Welcome! Today, we will explore creating a simple address book application using JavaScript Map. This task will help you understand manipulating Map in JavaScript, focusing on adding, retrieving, and deleting entries. By the end of this lesson, you'll have a solid grasp of these fundamental operations.

Introducing Methods to Implement

In this task, we will implement three methods to manage our address book:

  • addContact(name, phoneNumber): Adds a new contact. Returns false if the contact already exists; otherwise, it adds the contact and returns true. In this task, let's assume phone numbers do not change, so it's not allowed to overwrite the existing contact's number.
  • getContact(name): Retrieves the phone number for a given name. Returns undefined if the contact does not exist.
  • deleteContact(name): Deletes a contact with the given name. Returns true if the contact exists and is deleted, false otherwise.

Let's break down each method in detail in the next sections.

Step 1: Implementing `addContact`

This method adds a new contact to the address book with the given name and phoneNumber. If the contact already exists, it returns false. Otherwise, it adds the contact and returns true.

Question: Why do you think we need to check if the contact already exists?

Answer: To avoid duplicating existing entries. Also, if a contact with the same name already exists, we shouldn't allow overwriting its phone number in this method, as it's only for creation. Here is the method implementation:

JavaScript
1class AddressBook { 2 constructor() { 3 this.contacts = new Map(); 4 } 5 6 addContact(name, phoneNumber) { 7 if (this.contacts.has(name)) { 8 return false; 9 } 10 this.contacts.set(name, phoneNumber); 11 return true; 12 } 13} 14 15// Example usage: 16const addressBook = new AddressBook(); 17console.log(addressBook.addContact("Alice", "123-456-7890")); // true 18console.log(addressBook.addContact("Alice", "098-765-4321")); // false 19console.log(addressBook.contacts); // Map(1) { 'Alice' => '123-456-7890' }

In this method:

  • We verify if the contact already exists using if (this.contacts.has(name)).
  • If it exists, we return false.
  • If it doesn't exist, we add it to our Map and return true.
Step 2: Implementing `getContact`

This method retrieves the phone number associated with a given name. If the contact does not exist, it returns undefined.

Question: What do we gain by returning undefined when a contact doesn't exist?

Answer: It provides a clear indicator that the contact is not in the address book, allowing us to handle such cases gracefully.

Here is the method implementation:

JavaScript
1class AddressBook { 2 constructor() { 3 this.contacts = new Map(); 4 } 5 6 addContact(name, phoneNumber) { 7 if (this.contacts.has(name)) { 8 return false; 9 } 10 this.contacts.set(name, phoneNumber); 11 return true; 12 } 13 14 getContact(name) { 15 return this.contacts.get(name); 16 } 17} 18 19// Example usage: 20const addressBook = new AddressBook(); 21addressBook.addContact("Alice", "123-456-7890"); 22console.log(addressBook.getContact("Alice")); // '123-456-7890' 23console.log(addressBook.getContact("Bob")); // undefined

In this method:

  • We simply use return this.contacts.get(name);, which either returns the phone number or undefined if the contact does not exist.
Step 3: Implementing `deleteContact`

This method deletes a contact with the given name. If the contact exists and is deleted, it returns true. If the contact does not exist, it returns false.

Question: What could be a real-world consequence of not checking if the contact exists before deletion?

Answer: Attempting to delete a non-existent contact will not cause an error but will return false, ensuring no unintended changes happen.

Here is the method implementation:

JavaScript
1class AddressBook { 2 constructor() { 3 this.contacts = new Map(); 4 } 5 6 addContact(name, phoneNumber) { 7 if (this.contacts.has(name)) { 8 return false; 9 } 10 this.contacts.set(name, phoneNumber); 11 return true; 12 } 13 14 getContact(name) { 15 return this.contacts.get(name); 16 } 17 18 deleteContact(name) { 19 if (this.contacts.has(name)) { 20 this.contacts.delete(name); 21 return true; 22 } 23 return false; 24 } 25} 26 27// Example usage: 28const addressBook = new AddressBook(); 29addressBook.addContact("Alice", "123-456-7890"); 30console.log(addressBook.deleteContact("Alice")); // true 31console.log(addressBook.deleteContact("Bob")); // false 32console.log(addressBook.contacts); // Map(0) {}

In this method:

  • We verify if the contact exists using if (this.contacts.has(name)).
  • If it exists, we delete it using this.contacts.delete(name); and return true.
  • If the contact doesn't exist, we return false.
Why Maps are Efficient for These Tasks

Maps are particularly efficient for managing an address book due to several reasons:

  • Efficient Lookups and Insertions: Maps provide average O(1) time complexity for lookups, insertions, and deletions. This means managing contacts is very fast, even with a large number of them.
  • Preservation of Insertion Order: Maps maintain the order of entries according to their insertion sequence, which might be useful for displaying the contacts in the order they were added.
  • Flexibility with Keys: Unlike objects, keys in Maps can be any data type, not just strings. This offers higher flexibility in key management.
Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.