
I’ve been exploring the possibilities of using events to send data between Lightning components to keep them as generic and configurable as possible.
This map component was designed to highlight and show data for individual US states. The example below shows how the map can be configured on a Lightning page. As I tab out of each parameter on the right panel, it changes the map’s background colors, state colors, shows/hides state names and adds text to a set of states.
How it works: this component renders an SVG image dynamically. Its code goes through a list of states and their shapes, adding the colors and texts from the parameters on the right panel.
Below is a demo of the 3 components pulling the number of contacts an account has for each state.
However the US Map component itself doesn’t query data. I could make it fetch the data from an object but then that would make the component less generic because it would require me to hard code the SOQL query somewhere.
The ideal is to make a component so generic that one can just deploy it and configure it in the right panel and not have to modify the code again.
So for the purpose of keeping everything as flexible as possible, I’ve created 2 additional components that are not visible in the demo but they’re acting behind the map. One component to retrieve the data and another to format the data for the US Map component.
Each component doesn’t know exactly what the other is doing, just knows that it is supposed to receive some data, format it and pass along or display it.
This is similar to the MVC architecture: a Model that only knows how to obtain the data, a View that only knows how to present data and the Controller that sits in the middle managing the flow and conversion from data to presentation.

These components have been published at my GitHub account.

dataSourceQuery is the Model component: it accepts a SOQL query as parameter, retrieves the data then sends it out via an event.
componentHelper is the Controller component: it accepts a JSON format string as parameter, receives data via an event, rearranges that data using the JSON format and sends the formatted data out via another event. In this case I’ve configured it to accept data from events emitted by the dataSourceQuery.
countryMap is the View component: it accepts several map configuration parameters, and can also receive the same configuration data via an event. In this case I’ve configured it to accept data from componentHelper events.
dataSourceQuery was configured with the SOQL query below that counts the number of contacts per state. The query is SELECT MailingState, COUNT(Id) contCount FROM Contact WHERE AccountId = {recordId} GROUP BY MailingState

componentHelper was configured to format the data received from the dataSourceQuery (named SOQL1 above) and specify a light green color for states that have contacts and the count of contacts as the text to add to each state.

The JSON template references fields from the SOQL query and looks like this: {“stateColorPalette”: “lightgray,rgba(255, 0, 0, 0.1),hsla(120, 100%, 50%, 0.1)”,”backgroundColor”: “white”,”hideStateNames”: false,”displayOnlyTheseStateNames”:”[{MailingState}]”,”individualStateColors”:”[{MailingState}:lightgreen]”,”stateText”:”[{MailingState}:{contCount} contacts]”}
I want to improve and simplify that template language later.
countryMap was configured to receive parameters from the componentHelper (named TemplateHelper1 above):

Each component is “wired” to each other via the names (SOQL1, TemplateHelper1) in their configuration, so they should be reusable in different scenarios.
I’ve used the first option for Lightning Web Components to communicate between each other: the pubsub class.
Interestingly, pubsub has a comment at the top saying that in the future there will be another way of communicating events.
There are Javascript libraries that implement a more powerful alternative such as Flux, Redux, MobX or Hooks with useReducer that I intend to explore later.
I am open to suggestions! If you think of an useful component that could be implemented in this way, please let me know!
Leave a Reply