{"id":610,"date":"2019-07-20T22:05:00","date_gmt":"2019-07-21T03:05:00","guid":{"rendered":"https:\/\/blog.felineflock.com\/?p=610"},"modified":"2024-01-02T22:32:54","modified_gmt":"2024-01-03T04:32:54","slug":"how-to-create-an-us-map-lightning-web-component","status":"publish","type":"post","link":"https:\/\/blog.felineflock.com\/index.php\/2019\/07\/20\/how-to-create-an-us-map-lightning-web-component\/","title":{"rendered":"How to create an US Map Lightning Web Component"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"623\" src=\"https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/usmapcomponent-1024x623.png\" alt=\"\" class=\"wp-image-612\" srcset=\"https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/usmapcomponent-1024x623.png 1024w, https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/usmapcomponent-300x183.png 300w, https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/usmapcomponent-768x467.png 768w, https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/usmapcomponent.png 1183w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>I&#8217;ve been exploring the possibilities of using events to send data between Lightning components to keep them as generic and configurable as possible.<\/p>\n\n\n\n<p>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&#8217;s background colors, state colors, shows\/hides state names and adds text to a set of states.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"US Map Lightning Web Component being configured\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/DjZXZpesIKY?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><figcaption class=\"wp-element-caption\">US Map component configuration demo<\/figcaption><\/figure>\n\n\n\n<p><strong>How it works<\/strong>:&nbsp;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.<\/p>\n\n\n\n<p>Below is a demo of the 3 components pulling the number of contacts an account has for each state.<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"US Map Lightning Web Component - Demo with data\" width=\"500\" height=\"375\" src=\"https:\/\/www.youtube.com\/embed\/WbwLDzYJsjI?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><figcaption class=\"wp-element-caption\">US Map component demo<\/figcaption><\/figure>\n\n\n\n<p>However the US Map component itself doesn&#8217;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.<\/p>\n\n\n\n<p>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.<\/p>\n\n\n\n<p>So for the purpose of keeping everything as flexible as possible, I&#8217;ve created 2 additional components that are not visible in the demo but they&#8217;re acting behind the map. One component to retrieve the data and another to format the data for the US Map component.<\/p>\n\n\n\n<p>Each component doesn&#8217;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.<\/p>\n\n\n\n<p>This is\u00a0<strong>similar<\/strong>\u00a0to 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.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"541\" src=\"https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/analogyMVC-1024x541.png\" alt=\"\" class=\"wp-image-611\" srcset=\"https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/analogyMVC-1024x541.png 1024w, https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/analogyMVC-300x158.png 300w, https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/analogyMVC-768x405.png 768w, https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/analogyMVC.png 1432w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>These components have been published at my\u00a0<a href=\"https:\/\/github.com\/fmendes\/LightningWebComponentUSMap\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub account<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"884\" height=\"522\" src=\"https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/usmapgithub.png\" alt=\"\" class=\"wp-image-613\" srcset=\"https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/usmapgithub.png 884w, https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/usmapgithub-300x177.png 300w, https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/usmapgithub-768x454.png 768w\" sizes=\"auto, (max-width: 884px) 100vw, 884px\" \/><\/figure>\n\n\n\n<p><strong>dataSourceQuery<\/strong>&nbsp;is the Model component: it accepts a SOQL query as parameter, retrieves the data then sends it out via an event.<\/p>\n\n\n\n<p><strong>componentHelper<\/strong>&nbsp;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&#8217;ve configured it to accept data from events emitted by the&nbsp;<strong>dataSourceQuery<\/strong>.<\/p>\n\n\n\n<p><strong>countryMap<\/strong>&nbsp;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&#8217;ve configured it to accept data from&nbsp;<strong>componentHelper<\/strong>&nbsp;events.<\/p>\n\n\n\n<p><strong>dataSourceQuery<\/strong>\u00a0was configured with the SOQL query below that counts the number of contacts per state. The query is\u00a0<em>SELECT MailingState, COUNT(Id) contCount FROM Contact WHERE AccountId = {recordId} GROUP BY MailingState<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"610\" height=\"484\" src=\"https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/datasourcequery.png\" alt=\"\" class=\"wp-image-614\" srcset=\"https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/datasourcequery.png 610w, https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/datasourcequery-300x238.png 300w\" sizes=\"auto, (max-width: 610px) 100vw, 610px\" \/><\/figure>\n\n\n\n<p><strong>componentHelper<\/strong>\u00a0was configured to format the data received from the\u00a0<strong>dataSourceQuery<\/strong>\u00a0(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.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"610\" height=\"642\" src=\"https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/componenthelper.png\" alt=\"\" class=\"wp-image-615\" srcset=\"https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/componenthelper.png 610w, https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/componenthelper-285x300.png 285w\" sizes=\"auto, (max-width: 610px) 100vw, 610px\" \/><\/figure>\n\n\n\n<p>The JSON template references fields from the SOQL query and looks like this:&nbsp;<em>{&#8220;stateColorPalette&#8221;: &#8220;lightgray,rgba(255, 0, 0, 0.1),hsla(120, 100%, 50%, 0.1)&#8221;,&#8221;backgroundColor&#8221;: &#8220;white&#8221;,&#8221;hideStateNames&#8221;: false,&#8221;displayOnlyTheseStateNames&#8221;:&#8221;[<\/em><strong><em>{MailingState}<\/em><\/strong><em>]&#8221;,&#8221;individualStateColors&#8221;:&#8221;[<\/em><strong><em>{MailingState}<\/em><\/strong><em>:lightgreen]&#8221;,&#8221;stateText&#8221;:&#8221;[<\/em><strong><em>{MailingState}<\/em><\/strong><em>:<\/em><strong><em>{contCount}<\/em><\/strong><em>&nbsp;contacts]&#8221;}<\/em><\/p>\n\n\n\n<p>I want to improve and simplify that template language later.<\/p>\n\n\n\n<p><strong>countryMap<\/strong>\u00a0was configured to receive parameters from the\u00a0<strong>componentHelper<\/strong>\u00a0(named TemplateHelper1 above):<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"604\" height=\"640\" src=\"https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/countryMap.png\" alt=\"\" class=\"wp-image-616\" srcset=\"https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/countryMap.png 604w, https:\/\/blog.felineflock.com\/wp-content\/uploads\/2024\/01\/countryMap-283x300.png 283w\" sizes=\"auto, (max-width: 604px) 100vw, 604px\" \/><\/figure>\n\n\n\n<p>Each component is &#8220;wired&#8221; to each other via the names (SOQL1, TemplateHelper1) in their configuration, so they should be reusable in different scenarios.<\/p>\n\n\n\n<p>I&#8217;ve used the first option for Lightning Web Components to communicate between each other: the&nbsp;<a href=\"https:\/\/github.com\/trailheadapps\/lwc-recipes\/tree\/master\/force-app\/main\/default\/lwc\/pubsub\" target=\"_blank\" rel=\"noreferrer noopener\">pubsub class<\/a>.<\/p>\n\n\n\n<p>Interestingly, pubsub has a comment at the top saying that in the future there will be another way of communicating events.<\/p>\n\n\n\n<p>There are Javascript libraries that implement a more powerful alternative such as&nbsp;<a href=\"https:\/\/facebook.github.io\/flux\/\" target=\"_blank\" rel=\"noreferrer noopener\">Flux<\/a>,&nbsp;<a href=\"https:\/\/redux.js.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">Redux<\/a>,&nbsp;<a href=\"https:\/\/mobx.js.org\/\" target=\"_blank\" rel=\"noreferrer noopener\">MobX<\/a>&nbsp;or&nbsp;<a href=\"https:\/\/daveceddia.com\/usereducer-hook-examples\/\" target=\"_blank\" rel=\"noreferrer noopener\">Hooks with useReducer<\/a>&nbsp;that I intend to explore later.<\/p>\n\n\n\n<p>I am open to suggestions! If you think of an useful component that could be implemented in this way, please let me know!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;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 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-610","post","type-post","status-publish","format-standard","hentry","category-blog"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/blog.felineflock.com\/index.php\/wp-json\/wp\/v2\/posts\/610","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.felineflock.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.felineflock.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.felineflock.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.felineflock.com\/index.php\/wp-json\/wp\/v2\/comments?post=610"}],"version-history":[{"count":1,"href":"https:\/\/blog.felineflock.com\/index.php\/wp-json\/wp\/v2\/posts\/610\/revisions"}],"predecessor-version":[{"id":617,"href":"https:\/\/blog.felineflock.com\/index.php\/wp-json\/wp\/v2\/posts\/610\/revisions\/617"}],"wp:attachment":[{"href":"https:\/\/blog.felineflock.com\/index.php\/wp-json\/wp\/v2\/media?parent=610"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.felineflock.com\/index.php\/wp-json\/wp\/v2\/categories?post=610"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.felineflock.com\/index.php\/wp-json\/wp\/v2\/tags?post=610"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}