Project 2: Allow your Sales Reps to track their Goals and convert them to Accomplishments for their year end review with Lightning Web Components and 10 lines of Apex

Posted by

Hello readers! As stated in my previous project post Project 1: Building a Weather App in Salesforce: Using the weatherbit.io API to show Weather Data in a Lightning Web Component, one of my favorite hobbies is to wake up on a Sunday and think of different ideas and potential implementations and build them. This project gives your Sales Reps the ability to track their goals over the year, convert them into accomplishments when completed and have them ready when it’s time for their quarterly/yearly review with their manager.

As we get closer to the new year, I know I am constantly reflecting on what I have accomplished over this past year and the outstanding items I am looking to take on in 2020. I think this project is a really cool way of showing how components can talk to/ferry information to each other in a meaningful way that provides measurable growth for employees. As always, I love to write an overview of how this project corresponds to the business and what the requirement could look like:

“In the past, I haven’t had a good amount of insight into my sales rep’s goals and accomplishments over the course of a year. As the craziness of schedules/meetings ensues, a lot gets lost in the mix and typically business gets put in front of personal gain for establishing measurable growth and achievement. I would love to provide my reps with a tool to quickly input goals and their current progress, as well as the ability to convert their goals into accomplishments. As we sit down for our quarterly/yearly reviews and one on ones, this will give me meaningful insight into the achievements of my team and any outstanding items that I can help them work on.” – Joe Sales Manager

I wrote a little more code than I typically do for these small projects so I committed it to my GitHub repository labeled Goals and Accomplishments. There you can find everything you need to get started and improve the application. If you come up with any ideas or find any bugs, please let me know! The main principles covered here are:

One of the biggest and coolest aspects of these components is the event architecture thats driving the communication between components when certain aspects are invoked. You can see this nice football/pizza visual below to illustrate…

Here is an architecture diagram to show the overall structure of the components, their interaction with the database and what types of events are primarily used to communicate:

Let’s start with pub-sub (Publisher-Subscriber) events. Uh what???… Don’t worry, its really cool! To best explain this, let’s review a reminder of the observer pattern. For a reminder, let’s quickly review this diagram below.

“The observer pattern is a software design pattern in which an object, called the subject, maintains a list of its dependents, called observers, and notifies them automatically of any state changes, usually by calling one of their methods.” – Wikipedia definition

To put it simply, let’s say you subscribe to a particular magazine that you like. You choose your delivery date to be on the first of every single month. So the 1st rolls around and you are notified of the new monthly edition of your subscription. In this case, the magazine is the subject, the first of the month is the triggered event that sends the new edition of their magazine to its dependents, or subscribers. So whats the difference between the observer pattern and pub-sub architecture?

In publisher-subscriber architecture, the senders of the message (publishers) are not programmed to be sent directly to specific receivers (subscribers). This means that the publishing component and the subscribing component have no idea of each other’s existence. But how?

A broker. This message broker or event bus takes the messages from the publisher and distributes them to their respective destinations for which component is registering for it. Here is a diagram below comparing the two side by side:

Regular Custom Events with bubbling techniques are using to pass information from child to parent component when an action impacts the structure of the object and thus a new array must be constructed and rebuild utilizing the reactive @track property native to Lightning Web Components.

Another purpose of this component is to show that we can achieve elegant design and simple functionality with database manipulation through out of the box attributes. However, sometimes we need to perform an action, wait for it to finish, and then use a result to continue performing a necessary action within the application. In the release of ES8, we were blessed with async/await functions. Here’s a look at the syntax:

const doSomething = async () => {
    let result = await resolveAfterAPeriodOfTime(20);
    // console.log(result) => 20
}
const resolveAfterAPeriodOfTime = (x) => {
    return new Promise(resolve => {
        setTimeout(() => {
        resolve(x + x);
    }, 2000);
  });
}
doSomething();

Whats useful about this pattern is that we are able to leverage imported database actions such as createRecord to wait for the Id to be returned so that we can incorporate it into an object in memory to know how to further process it later down the road in the workflow. These out of the box DML functions available to us allow us to limit the amount of backend code we are writing to only grabbing a list of records on page load to then process and show in the UI. In this case, we only had to write 10 lines of Apex to initially retrieve the goal and accomplishment records and the rest is done completely on the front end.

On a final note, it’s always important to utilize ES6 modules when we can. Think of these as modern static resources in salesforce context. This gives us the ability to share code across multiple Lightning Web Components and even across Lightning Components as well. For more information, please see my post on The difference between Lightning Components and Lightning Web Components, Part 2, JavaScript and Modules. Here is a screenshot and screen share of the component in its final state. As always, please let me know if you have any questions. Merry Christmas and Happy Coding!

Potential enhancements to the current functionality:

  • If the most recent goal exceeds a certain amount of time, throw an alert that says something like ‘It looks like you haven’t submitted or converted any goals in a while! Think of one thing you’d like to work on and add it here’
  • If a user changes the status to ‘Completed’, it invokes the same process that checking the accomplishment radio button does and moves it to the accomplishment section