<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: pbj</title>
    <description>The latest articles on DEV Community by pbj (@pbj).</description>
    <link>https://dev.to/pbj</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F33629%2Fd77ab03f-c24e-4329-8529-bd3616f7c7f1.jpeg</url>
      <title>DEV Community: pbj</title>
      <link>https://dev.to/pbj</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pbj"/>
    <language>en</language>
    <item>
      <title>Creating dynamic, reactive UIs for Shopify without React</title>
      <dc:creator>pbj</dc:creator>
      <pubDate>Mon, 19 Nov 2018 14:44:30 +0000</pubDate>
      <link>https://dev.to/pbj/creating-dynamic-reactive-uis-for-shopify-without-react-3bn1</link>
      <guid>https://dev.to/pbj/creating-dynamic-reactive-uis-for-shopify-without-react-3bn1</guid>
      <description>

&lt;p&gt;There are a ton of sites on the internet which rely upon Shopify to power their e-commerce needs. Almost all of those websites have interactions which are responsible for a handful of UI-based updates. Managing those UI updates between various JavaScript files can sometimes get carried away, leading to unorganized or closely-coupled code. &lt;/p&gt;

&lt;p&gt;The most recent site I built, &lt;a href="https://hicolugo.com"&gt;Colugo&lt;/a&gt;, uses Shopify and I ran into this thought while planning the build. I knew I’d need to share component state(s) between components and the site overall. I considered adding React but then decided to use the publisher-subscriber pattern via an events library may be a simpler approach. And as most clickbait articles would say: &lt;em&gt;The results will shock you!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;Using Events in Shopify&lt;/h2&gt;

&lt;p&gt;It came to my surprise when I found out Shopify has an events library pre-packaged within Slate. By way of Webpack, Shopify ships with an event module, “events.js”, which implements the &lt;a href="https://www.npmjs.com/package/events"&gt;Node.js events module for browser environments&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This approach can be achieved with any other events module as well. &lt;/p&gt;

&lt;h2&gt;Dynamic, Reactive User Interfaces&lt;/h2&gt;

&lt;p&gt;My goal while building the e-commerce site for Colugo was to reduce direct coupling between my components as much as possible. Using a publisher-subscriber pattern to manage events made decoupling a breeze and ended with a much more organized code base.&lt;/p&gt;

&lt;p&gt;Knowing I’d use this pattern up front enabled me to map out a few components which would require dynamic UI components and what some states would look like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  When a user adds an item to the cart

&lt;ul&gt;
&lt;li&gt;If successful, display the minicart and/or confirmation message&lt;/li&gt;
&lt;li&gt;If unsuccessful, display error messaging.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;  When a user clicks the mobile “cart” icon to display the menu

&lt;ul&gt;
&lt;li&gt;If the mobile menu is visible, close it and display the mini cart&lt;/li&gt;
&lt;li&gt;If the mobile menu is not visible, open the mini cart. &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;When a user views the product detail page

&lt;ul&gt;
&lt;li&gt;If a user selects a product color, then scrolls:

&lt;ul&gt;
&lt;li&gt;Display current color selection&lt;/li&gt;
&lt;li&gt;User may update selection&lt;/li&gt;
&lt;li&gt;New selection reflected between shared components&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;If a user updates color selection:

&lt;ul&gt;
&lt;li&gt;Display current quantity&lt;/li&gt;
&lt;li&gt;When a user scrolls back up, new quantity should correctly display between shared components&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we were using React, a lot of this UI interaction would be composed via Redux or a HOC passing props and event handlers to smaller components. Since we can’t easily use React with Shopify we needed another way to share small pieces “state” updates between components.&lt;/p&gt;

&lt;h2&gt;Enter Event.js&lt;/h2&gt;

&lt;h3&gt;Using Namespaces For Organized Events&lt;/h3&gt;

&lt;p&gt;Because our events were being fired in more than one module, we created a small object which exposed the event “types”. It looks like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export default eventTypes = {
    menuUpdate: 'colugo:menu-update',
    mobileMenuUpdate: 'colugo:mobile-nav-update',
    cartUpdate: 'colugo:cart-update',
    variantUpdate: 'colugo:variant-update',
    productNavUpdate: 'colugo:pn-udpate',
    miniCartUpdate: 'colugo:minicart-update',
    recircUpdate: 'colugo:recirc-update',
    recircCartUpdate: 'colugo:recirc-cart-add',
};
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This module isn’t special. It provides a consistent way to set up named event publications and subscriptions I know won’t collide within modules.&lt;/p&gt;

&lt;h3&gt;Payloads&lt;/h3&gt;

&lt;p&gt;Within each event, we passed in a payload object which represents the data any and all subscribers could use to update their UI. In the case of Colugo, the payloads were usually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Product

&lt;ul&gt;
&lt;li&gt;Variant

&lt;ul&gt;
&lt;li&gt;ID&lt;/li&gt;
&lt;li&gt;Title&lt;/li&gt;
&lt;li&gt;Price&lt;/li&gt;
&lt;li&gt;Inventory&lt;/li&gt;
&lt;li&gt;Color&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cart

&lt;ul&gt;
&lt;li&gt;Total Count&lt;/li&gt;
&lt;li&gt;Items Array&lt;/li&gt;
&lt;li&gt;Cart Update (Success or Failure)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Display States

&lt;ul&gt;
&lt;li&gt;Mini Cart Toggling&lt;/li&gt;
&lt;li&gt;Menu Toggling&lt;/li&gt;
&lt;li&gt;Newsletter Modals&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Publishing Events&lt;/h3&gt;

&lt;p&gt;Now that we have our namespaces setup along with our payloads, we can publish an event:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import events from 'events'
import eventTypes from 'eventTypes'

events.emit(eventTypes.variantUpdate, {
    ... payload object
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Subscribing To Events&lt;/h3&gt;

&lt;p&gt;Our event bus now makes subscribing events super easy. Bringing together our namespace and payload, subscribing to events looks like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import events from 'events'
import eventTypes from 'eventTypes'

events.on(eventTypes.variantUpdate, (payload) =&amp;gt; {
    ... run whatever you want
}));
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This separates UI updates from the events themselves. For instance, within Colugo, when a user selects a different product color a few UI changes happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;New color is selected as active&lt;/li&gt;
&lt;li&gt;Product variant name is updated&lt;/li&gt;
&lt;li&gt;Product price is updated&lt;/li&gt;
&lt;li&gt;Product inventory may be updated&lt;/li&gt;
&lt;li&gt;Product gallery images may be updated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In past projects, I may have written all the UI changes into one “products.js” file encapsulating all of those DOM elements which make up the UI which changes. While this worked, we also had to keep track of multiple UI components, track which one was changed, when it changed and then propagate changes to other components. In a nutshell, the old approach meant a lot of arrays and looping.&lt;/p&gt;

&lt;p&gt;In the case of Colugo, if a user interacted with the color picker, we subscribe to the &lt;code&gt;variantUpdate&lt;/code&gt; event and call the component methods to update the UI.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import events from 'events'
import eventTypes from 'eventTypes'

events.on(eventTypes.variantUpdate, (product) =&amp;gt; {
    // destructure object for props if necessary
    //
    colorPicker.setActiveColor(product.variant.color)
    productContent.udpateTitle(product.title)
    productContent.updatePrice(product.price)
    productContent.updateInveotyr(product.inventoryCount)
    productGallery.updateGallery(product.variant.images)
    ...
    ...
});

By leveraging the publisher-subscriber pattern and the built-in events library in Webpack we’re able to manage UI changes in a clean, consistent and organized manner. Our footprint is kept to a minimum and UI components (existing or newly made) can easily subscribe to events with very little overhead.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;h3&gt;Aside on “events”&lt;/h3&gt;

&lt;p&gt;Throughout this article we use the term “events”. It’s worth clarifying we are not referring to browser events like “click” or “onchange” event. With the publisher-subscriber pattern, there are no browser events being fired so it can be beneficial for performance as well.&lt;/p&gt;

&lt;p&gt;Helpful reference for further reading:&lt;a href="https://stackoverflow.com/questions/27677692/performance-cost-of-pubsub-excessive-events-and-event-handlers-in-javascript"&gt;https://stackoverflow.com/questions/27677692/performance-cost-of-pubsub-excessive-events-and-event-handlers-in-javascript&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;IRL Examples&lt;/h4&gt;

&lt;p&gt;Rather than just talking about the work, feel free to check out &lt;a href="https://hicolugo.com/products/compact-stroller?variant=14529068662854"&gt;Colugo's Product Detail Page&lt;/a&gt; and poke around! You’ll see how pieces of UI interact with one another. Here are a few areas you can look at which take advantage of the publisher-subscriber method and events.js&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select a color on a product page

&lt;ul&gt;
&lt;li&gt;This should change the image gallery and some content in the hero&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Scroll down and use the sticky color picker to update the color

&lt;ul&gt;
&lt;li&gt;This will sync up the content and gallery to the new current selection&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Add a product to the cart 
-If successful, will open the cart and update the cart number count&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Demos&lt;/h4&gt;

&lt;p&gt;Pub/Sub - Counter Example&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/pbj/embed/QZPJvR?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt; &lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;Pub/Sub - Cart Notification&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/pbj/embed/LgvMga?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt; &lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;Pub/Sub - Active Element&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/pbj/embed/oQZKRz?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt; &lt;/iframe&gt;&lt;/p&gt;

&lt;p&gt;Big thanks to &lt;a href="http://www.zeespencer.com/"&gt;Zee Spencer&lt;/a&gt; for reviewing and editing this post before publishing.&lt;/p&gt;


</description>
      <category>shopify</category>
      <category>dynamicui</category>
      <category>pubsubpattern</category>
    </item>
    <item>
      <title>Who Cares?</title>
      <dc:creator>pbj</dc:creator>
      <pubDate>Mon, 18 Sep 2017 22:05:48 +0000</pubDate>
      <link>https://dev.to/pbj/who-cares</link>
      <guid>https://dev.to/pbj/who-cares</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Does your app work with Vue.js even though all your friends are using React.js? If yes, then who cares.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do you still get work without having a portfolio? If yes, then who cares?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do you learn better from reading books instead of watching videos? If yes, then who cares? &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do you earn money by building sites with PHP instead of a Ruby (on Rails)? If yes, then who cares?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Did you just buy new running shoes right before the new All Birds released? If yes, who cares?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Did you learn JavaScript by way of  jQuery? If yes, who cares?&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This list could go on forever but you get the picture. The reality with our work, and our lives, is we all do things differently. Unless you’re doing something really wrong, who cares?&lt;/p&gt;

&lt;p&gt;If your intentions are well-formed and your work is well-crafted all that matters is helping someone, or something, progress forward. &lt;/p&gt;

&lt;p&gt;You may not work at the hottest startup or on the newest product. If you enjoy your life, work and everything in between then who cares about what others are doing? You don’t need to follow the "herd" to be happy. You can achieve your personal, professional and financial (or any other) goals by following your intuition, gut and common sense. You can be you and still be happy.&lt;/p&gt;

&lt;p&gt;We could spend our days arguing over skeuomorphic design vs flat and the "resurgence" of brutalist sites but will it make our lives, our customers’ lives, or families’ lives better?&lt;/p&gt;

&lt;p&gt;Sure, you can have an opinion, you can voice it, you can scream it from the tallest rooftops but here's the kicker, &lt;strong&gt;your opinion may not be someone’s fact&lt;/strong&gt;. It isn’t a truth to be told and held over the heads of others in or outside our industry. Your way of doing something may be right for you and your organization, but it may wrong for a friend or another company. &lt;/p&gt;

&lt;p&gt;Our peers are a good barometer for quality but we still must trust our gut to find the right fit, tool, direction. And ultimately, who cares if the decision you make goes directly against the herd as long as you’re happy and it’s positive for you without negatively impacting others. &lt;/p&gt;

&lt;p&gt;Continue to be you, try new things and be open. If you pause because of what other’s may think just ask yourself one question - who cares?&lt;/p&gt;

&lt;p&gt;Big thanks to &lt;a href="http://graybike.co/"&gt;Pavan Trikutam&lt;/a&gt;, &lt;a href="http://sandpiper.co/"&gt;Monte Brown&lt;/a&gt;, &lt;a href="http://www.sofetch.io/"&gt;Corey Grusden&lt;/a&gt; and &lt;a href="http://www.kylecrawford.co/"&gt;Kyle Crawford&lt;/a&gt; for reviewing and editing this post before publishing. &lt;/p&gt;

&lt;p&gt;&lt;em&gt;This was originally published on May 24, 2017 on &lt;a href="http://pbj.me/writing/who-cares.html"&gt;pbj.me/writing/who-cares.html&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>developer</category>
    </item>
  </channel>
</rss>
