DEV Community

Cover image for Building a Project with JavaScript Objects.
Elijah Trillionz
Elijah Trillionz

Posted on

Building a Project with JavaScript Objects.

Hello World!, this article is a project template. More like a complete project but just Javascript (i.e no HTML or CSS).

I have not been a fan of JavaScript Objects and Classes, not that I don't understand the fundamentals but I found it not too necessary to worry about as I considered Functional Programming as a simpler approach. These have been my thoughts for long and all my projects so far were all with functional programming, but when I took the CodeCademy's JavaScript Course; I discovered my love for Object-Oriented Programming, and for me, I think it's way simpler, especially if using Getters and Setters.

So after I was done with the JavaScript Objects module of the course, there was this project they (CodeCademy) were going to build i.e Meal Maker. I couldn't access it as a free user, but I understood the purpose of making the project i.e to make use of Getters and Setters in a real-life project.

There was one problem, I had no idea of what a Meal Maker does or how it usually works, but I had a great idea to practice Getters and Setters; an Appointment Booking App. Brilliant right? Yeah, I know, so what it does is simply book appointments for people with business users.

Say I am Elon Musk (which I am not), I can create an account with this app as such other users can book appointments with me.

Now Elon Musk is not gonna be the only user with a business account, we will use Factory Functions (not Classes) to duplicate and have any amount of business account we want.

This app may be basic, but it contains all the difficult parts of making an appointment booking app. Have in mind that the purpose of this article is not to show you one of the ways you can make an appointment booking app, but to show you how Getters and Setters can be very handy in projects like this.

If you do not know JavaScript Getters and Setters or JavaScript Objects, i recommend going through CodeCademy's JS Objects Course.

Enough with the writing, let's get to coding. Scroll down to see the complete code or simply visit GitHub for the code.

// alert: am tired of using John Doe, i wanna use Elon Musk
const elonMusk = {
  _hoursfree: [10, 12, 9], // currently hard-coded, but will change in time
};
Enter fullscreen mode Exit fullscreen mode

The reason for the underscore (_) before the hoursFree property is because I intentionally do not want that to be accessed directly. A programmer should know that and keep to that. But we would need to access the hours Elon Musk is free, to do that we will use JavaScript Getters i.e

const elonMusk = {
  _hoursFree: [10, 12, 9],

  get hoursFree() {
    return this._hoursFree; // can now be accessed legitimately
  },
};
Enter fullscreen mode Exit fullscreen mode

Now we want to add more properties to the elonMusk object

const elonMusk = {
  _hoursFree: [10, 12, 9],
  acceptedPurpose: 'any',
  pendingMeetongs: [], // meetings yet to be approved by Elon Musk
  declinedMeetings: [], // meetings not approved by Elon Musk
  approvedMeetings: [], // meetings approved by Elon Musk
  canceledMeetings: [], // meetings already approved but later canceled maybe something came up
  _feedback: '', // feedback to the booking user (user making the booking)

  get hoursFree() {
    return this._hoursFree;
  },

  get feedBack() {
    return this._feedback); // simply return a feedback
  },
};
Enter fullscreen mode Exit fullscreen mode

The acceptedPurpose property simply represents the current purpose Elon Musk wants to accept. Let's say the design of the app has in it that the purpose of a meeting can be set weekly or daily as the case may be; by Elon Musk. Say the acceptedPurpose options provided by the app is business, family, fun, or any

So for now we are assuming Elon Musk is available for any type of meeting be it a business meeting, fun meeting, family meeting. Currently hard-coded will change later.

Now let's begin using Setters. Say we want to book a meeting with Elon Musk, how would we do it

  // still in the elonMusk object, just under the feedBack getter
  set newMeeting(time) {
    if (this._hoursFree.indexOf(time) !== -1) {
      this.pendingMeetings.push(time);
      this._feedback =
        'Your meeting was sent successfully. Elon Musk can now review and approve or decline';
    } else {
      this._feedback = 'Time not suitable for Elon Musk';
    }
  },

// outside of the elonMusk object
elonMusk.newMeeting = 10
console.log(elonMusk.feedBack)
Enter fullscreen mode Exit fullscreen mode

This is very basic, there is more to setting a meeting which we will get back to. But first, let's analyze this;

  • We checked if the time provided by the user is suitable with Elon Musk by comparing it to his provided free hours.
  • If true, we added the time to the pendingMeetings array. and gave a feedback.
  • If false, we simply return a feedback to the user making this booking.

A meeting should not just contain the time, Elon Musk of course would need more information about this meeting i.e

Creating Meetings:

// still in the elonMusk object, just under the feedBack getter
  set newMeeting(meeting) {
    const { name, time, purpose } = meeting;

    if (
      this._hoursFree.indexOf(time) !== -1 &&
      this.acceptedPurpose === 'any'
    ) {
      this.pendingMeetings.push(meeting);

      this._feedback = `${name}, your meeting was sent successfully. Elon Musk can now review and approve or decline`;
    } else if (this.acceptedPurpose === purpose.toLowerCase()) {
      this.pendingMeetings.push(meeting);

      this._feedback = `${name}, your meeting was sent successfully. Elon Musk can now review and approve or decline`;
    } else {
      this._feedback = `${name}, this meeting is not suitable for Elon Musk`;
    }
  },
  }

// outside of the elonMusk object
const clientMeeting = {id: 10, name: 'Bill Gates', time: 10, purpose: 'fun'};

elonMusk.newMeeting = clientMeeting;
console.log(elonMusk.feedBack);
Enter fullscreen mode Exit fullscreen mode

We just made it a little spicy, shouldn't be difficult to comprehend. We included id, name, and purpose to time to make up the meeting object.
The meeting will be sent successfully if;

  • the acceptedPurpose of Elon Musk is set to any and if the time of meeting from booking user is an item in the hoursFree array of Elon Musk.
  • the acceptedPurpose of Elon Musk is similar to the purpose provided by the booking user

Now let's start approving, declining, and canceling meetings

Approving Meetings:

// still in the elonMusk object, right under the newMeeting
  set approveMeeting(id) {
    const previewingMeeting = this.pendingMeetings.filter((meeting) => {
      return meeting.id === id; // filter out a meeting with its id and preview
    })[0];

    // approve previewing meeting and mark the previewingMeeting.time as a booked hour
    this.approvedMeetings.push(previewingMeeting); // note that approvedMeetings with a 'd' is the array while approveMeeting without a 'd' is the setter
    this._hoursFree.splice(this._hoursFree.indexOf(previewingMeeting.time), 1);

    this._feedback = `${previewingMeeting.name}, your meeting has been approved, time of meeting: ${previewingMeeting.time}`;
  },

// outside the elonMusk object;
elonMusk.newMeeting = clientMeeting //clientMeeting already declared before, scroll up
elonMusk.approveMeeting = clientMeeting.id;
console.log(elonMusk.feedBack);
Enter fullscreen mode Exit fullscreen mode

The approveMeeting setter is not having any conditional statement because it is meant to go straight to the point that is; approves the meeting. So this can be attributed to a button that says 'Approve Meeting', and when clicked by Elon, the meeting is approved and sent to the approvedMeetings array.

If a meeting is approved, then it means a particular hour of Elon Musk has been booked. For that, we should endeavor to remove that booked hour to avoid two or more meetings booked to a particular hour. So for that, we used the splice method to remove that hour. You can log the current hoursFree in the console to see the result of that i.e console.log(elonMusk.hoursFree)

Declining Meetings:

// still in the elonMusk object, right under the approveMeeting
  set declineMeeting(id) {
    const previewingMeeting = this.pendingMeetings.filter((meeting) => {
      return meeting.id === id; // filter out a meeting with its id and preview
    })[0];


    this.declinedMeetings.push(previewingMeeting); // note that declinedMeetings with a 'd' is the array while declineMeeting without a 'd' is the setter

    this._feedback = `${previewingMeeting.name}, your meeting was declined for reasons best known to Elon Musk`;
  },

// outside the elonMusk object;
elonMusk.newMeeting = clientMeeting //clientMeeting already declared before, scroll up
elonMusk.declineMeeting = clientMeeting.id;
console.log(elonMusk.feedBack);
Enter fullscreen mode Exit fullscreen mode

Something to note is that the delineMeeting setter is a manual declining by Elon Musk, automatic declining was never added to the pendingBookings array. In other words, bookings that were added to the pendingBookings array are bookings that needed the business account owner (Elon Musk now) to review.

Automatic declining were done when either the time or purpose was not suitable for Elon Musk as provided in the hoursFree array and the acceptedPurpose string.

Canceling Meetings:

// still in the elonMusk object, right under the declineMeeting
    set cancelMeeting(id) {
    // the meeting has to be approved first
    const previewingMeeting = this.approvedMeetings.filter((meeting) => {
      return meeting.id === id;
    })[0];

    this._hoursFree.push(previewingMeeting.time); // make the hour of the canceled meeting a free hour
    this.canceledMeetings.push(previewingMeeting); // add canceled meeting to the array of canceled meetings
    this.approvedMeetings.splice(previewingMeeting, 1); // remove canceled meeting from approved meeting array

    this._feedback = `${previewingMeeting.name}, your meeting with Elon Musk scheduled at ${previewingMeeting.time} has been canceled by Elon Musk. Don't ask me why? am not Elon Musk.`;
  },

// outside the elonMusk object
elonMusk.newMeeting = clientMeeting; //clientMeeting already declared above
elonMusk.approveMeeting = clientMeeting.id; // approve meeting first
elonMusk.cancelMeeting = clientMeeting.id;
console.log(elonMusk.feedBack);
Enter fullscreen mode Exit fullscreen mode

Pretty straightforward. One thing you could add is a setter to remove free hours from the hoursFree array. If a meeting got canceled, the scheduled hour is automatically regarded as a free hour; but if Elon Musk doesn't want that hour to be free anymore He can simply click a button to remove that hour from being free (manually).

Requesting Free Hour Cancelation:

// still in the elonMusk object, right under the cancelMeeting
  set requestHourCancelation(hr) {
    if (this._hoursFree.indexOf(hr) !== -1) {
      this._hoursFree.splice(this._hoursFree.indexOf(hr), 1);
    }
  }

// outside of the elonMusk object
elonMusk.requestHourCancelation = 10;
console.log(elonMusk.hoursFree);
Enter fullscreen mode Exit fullscreen mode

Elon Musk Booking Object:

const elonMusk = {
  _hoursFree: [10, 12, 9],
  acceptedPurpose: 'family',
  pendingMeetings: [], // meetings yet to be approved by Elon Musk
  declinedMeetings: [], // meetings not approved by Elon Musk
  approvedMeetings: [], // meetings approved by Elon Musk
  canceledMeetings: [], // meetings already approved but later canceled maybe something came up
  _feedback: '', // feedback to the booking user (user making the booking)

  get hoursFree() {
    return this._hoursFree;
  },

  get feedBack() {
    this._feedback; // simply return a feedback.
  },

  set newMeeting(meeting) {
    const { name, time, purpose } = meeting;

    if (
      this._hoursFree.indexOf(time) !== -1 &&
      this.acceptedPurpose === 'any'
    ) {
      this.pendingMeetings.push(meeting);

      this._feedback = `${name}, your meeting was sent successfully. Elon Musk can now review and approve or decline`;
    } else if (this.acceptedPurpose === purpose.toLowerCase()) {
      this.pendingMeetings.push(meeting);

      this._feedback = `${name}, your meeting was sent successfully. Elon Musk can now review and approve or decline`;
    } else {
      this._feedback = `${name}, this meeting is not suitable for Elon Musk`;
    }
  },

  set approveMeeting(id) {
    const previewingMeeting = this.pendingMeetings.filter((meeting) => {
      return meeting.id === id;
    })[0];

    // approve previewing meeting and mark the previewingMeeting.time as a booked hour
    this.approvedMeetings.push(previewingMeeting); // note that approvedMeetings is the array while approveMeeting is the setter
    this._hoursFree.splice(this._hoursFree.indexOf(previewingMeeting.time), 1);

    this._feedback = `${previewingMeeting.name}, your meeting has been approved, time of meeting: ${previewingMeeting.time}`;
  },

  set declineMeeting(id) {
    const previewingMeeting = this.pendingMeetings.filter((meeting) => {
      return meeting.id === id;
    })[0];

    this.declinedMeetings.push(previewingMeeting); // note that declinedMeetings is the array while declineMeeting is the setter

    this._feedback = `${previewingMeeting.name}, your meeting was declined for reasons best known to Elon Musk`;
  },

  set cancelMeeting(id) {
    // the meeting has to be approved first
    const previewingMeeting = this.approvedMeetings.filter((meeting) => {
      return meeting.id === id;
    })[0];

    this._hoursFree.push(previewingMeeting.time); // make the hour of the canceled meeting a free hour
    this.canceledMeetings.push(previewingMeeting); // add canceled meeting to the array of canceled meetings
    this.approvedMeetings.splice(previewingMeeting, 1); // remove canceled meeting from approved meeting array

    this._feedback = `${previewingMeeting.name}, your meeting with Elon Musk scheduled at ${previewingMeeting.time} has been canceled by Elon Musk. Don't ask me why? am not Elon Musk.`;
  },

  set requestHourCancelation(hr) {
    if (this._hoursFree.indexOf(hr) !== -1) {
      this._hoursFree.splice(this._hoursFree.indexOf(hr), 1);
    }
  },
};
Enter fullscreen mode Exit fullscreen mode

Have multiple business owners:

Say we want Bill Gate to have his business account and maybe Larry Page as well, we don't have to copy the codes in the elonMusk object and start pasting; that's just unnecessary. Since the getters and setters in the elonMusk object are going to be similar to the others (of course they should be), we would simply make instances for every user.

Usually, this can be done with JavaScript classes, but we will not use classes here (but we will in the future), instead, we will use factory functions which I recently learned from Codecademy.com.
This is how it's done.

// make a function and return all properties, getters and setters in the elonMusk object
function businessUser(businessName, _hoursFree, acceptedPurpose) {
  // the three parameters above are properties of this object that are going to vary with different business users
  return {
    businessName,
    _hoursFree,
    acceptedPurpose,
    pendingMeetings: [], // meetings yet to be approved by Elon Musk
    declinedMeetings: [], // meetings not approved by Elon Musk
    approvedMeetings: [], // meetings approved by Elon Musk
    canceledMeetings: [], // meetings already approved but later canceled maybe something came up
    _feedback: '', // feedback to the booking user (user making the booking)

    get hoursFree() {
      return this._hoursFree;
    },

    get feedBack() {
      this._feedback; // simply return a feedback.
    },

    set newMeeting(meeting) {
      const { name, time, purpose } = meeting;

      if (
        this._hoursFree.indexOf(time) !== -1 &&
        this.acceptedPurpose === 'any'
      ) {
        this.pendingMeetings.push(meeting);

        this._feedback = `${name}, your meeting was sent successfully. ${this.businessName} can now review and approve or decline`;
      } else if (this.acceptedPurpose === purpose.toLowerCase()) {
        this.pendingMeetings.push(meeting);

        this._feedback = `${name}, your meeting was sent successfully. ${this.businessName} can now review and approve or decline`;
      } else {
        this._feedback = `${name}, this meeting is not suitable for ${this.businessName}`;
      }
    },

    set approveMeeting(id) {
      const previewingMeeting = this.pendingMeetings.filter((meeting) => {
        return meeting.id === id;
      })[0];

      // approve previewing meeting and mark the previewingMeeting.time as a booked hour
      this.approvedMeetings.push(previewingMeeting); // note that approvedMeetings is the array while approveMeeting is the setter
      this._hoursFree.splice(
        this._hoursFree.indexOf(previewingMeeting.time),
        1
      );

      this._feedback = `${previewingMeeting.name}, your meeting has been approved, time of meeting: ${previewingMeeting.time}`;
    },

    set declineMeeting(id) {
      const previewingMeeting = this.pendingMeetings.filter((meeting) => {
        return meeting.id === id;
      })[0];

      this.declinedMeetings.push(previewingMeeting); // note that declinedMeetings is the array while declineMeeting is the setter

      this._feedback = `${previewingMeeting.name}, your meeting was declined for reasons best known to ${this.businessName}`;
    },

    set cancelMeeting(id) {
      // the meeting has to be approved first
      const previewingMeeting = this.approvedMeetings.filter((meeting) => {
        return meeting.id === id;
      })[0];

      this._hoursFree.push(previewingMeeting.time); // make the hour of the canceled meeting a free hour
      this.canceledMeetings.push(previewingMeeting); // add canceled meeting to the array of canceled meetings
      this.approvedMeetings.splice(previewingMeeting, 1); // remove canceled meeting from approved meeting array

      this._feedback = `${previewingMeeting.name}, your meeting with ${this.businessName} scheduled at ${previewingMeeting.time} has been canceled by ${this.businessName}. Don't ask me why? am not ${this.businessName}.`;
    },

    set requestHourCancelation(hr) {
      if (this._hoursFree.indexOf(hr) !== -1) {
        this._hoursFree.splice(this._hoursFree.indexOf(hr), 1);
      }
    },
  };
}
Enter fullscreen mode Exit fullscreen mode

Everything in the businessUser function is all we need to create a million functioning business accounts. Let's try creating three and accessing their properties

const larryPage = businessUser('Larry Page', [15, 12, 9], 'any');
console.log(larryPage.hoursFree);
const willSmith = businessUser('Will Smith', [9, 10], 'fun');
console.log(willSmith.hoursFree);
const billGates = businessUser(
  'Bill Gates',
  [11, 10, 9, 8, 7, 6, 5, 4, 3, 2],
  'any'
); // Mr. Gates is always free.
console.log(billGates.hoursFree);
Enter fullscreen mode Exit fullscreen mode

Get the code on GitHub, Building a Project with JavaScript Objects. Don't forget to leave a star.

Conclusion

It is important to note that all of the setters above can be replaced with methods and will still work fine, but since we are focusing on setters we might as well use it all through. I intend to make a library on my next post using JavaScript Classes and Methods, it is completely different from this and more advanced and enjoyable than this. It's gonna be fun.

I hope you learned a lot as I did. Heads up, I have something (a project) awesome coming your way soon as a developer (you're gonna love it). Thanks for reading, don't forget to leave your comments below if you have any complaints or stories (I love stories), also don't forget to share with your colleagues. If you wish to support me then you can buy me a coffee. I appreciate.

Top comments (7)

Collapse
 
eissorcercode99 profile image
The EisSorcer

Just started objects on Codecademy so this article is an awesome head start as to where ill be end of chapter. Any recommendations for self taught coders who are just learning the basics of OOP?

Collapse
 
elijahtrillionz profile image
Elijah Trillionz

Oh. Good for you.
What I will recommend is to go through their project building. Try to build a project from what you learn for each module. It's gonna help you understand it better.

Collapse
 
eissorcercode99 profile image
The EisSorcer

Thanks for the response

Collapse
 
sskanishk profile image
Kanish Malviya

good article, really appreciated.
thanks :)

Collapse
 
elijahtrillionz profile image
Elijah Trillionz

Thank you.

Collapse
 
maxoralbay profile image
Max Oralbay

I have never use like it. i saw on git and i think i will use on jobs. Thanks

Collapse
 
elijahtrillionz profile image
Elijah Trillionz

Ok that's nice