<?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: hariseldon27</title>
    <description>The latest articles on DEV Community by hariseldon27 (@hariseldon27).</description>
    <link>https://dev.to/hariseldon27</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%2F789323%2Feca1acfd-9275-4734-95ca-4afd8d4e5a85.jpg</url>
      <title>DEV Community: hariseldon27</title>
      <link>https://dev.to/hariseldon27</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hariseldon27"/>
    <language>en</language>
    <item>
      <title>Why I care about headless architecture.</title>
      <dc:creator>hariseldon27</dc:creator>
      <pubDate>Sat, 18 Jun 2022 16:40:17 +0000</pubDate>
      <link>https://dev.to/hariseldon27/why-i-care-about-headless-architecture-3hlk</link>
      <guid>https://dev.to/hariseldon27/why-i-care-about-headless-architecture-3hlk</guid>
      <description>&lt;h2&gt;
  
  
  Why I can't post on social media regularly
&lt;/h2&gt;

&lt;p&gt;In the social media world there is this term, 'Content is King, and consistency is Queen.' I'm not a huge social media user for my own personal needs, and I know that consistency is my biggest issue with it. Unless I plan an entire campaign, and have 90% of it in the can before launching, I'll most likely fall off the posting-wagon.&lt;/p&gt;

&lt;p&gt;What helps me keep my social media posting on track? Strategic planning and data management. There are two critical tools needed here: strategic planning requires a notebook and pen (or a text editor), and data management is greatly aided with a content management system (CMS from here out). &lt;/p&gt;

&lt;h2&gt;
  
  
  Data drives the digital experience
&lt;/h2&gt;

&lt;p&gt;We are in a world of 'infinite information' according to Raygun, the web monitoring company, and that data has to be stored and presented somehow.&lt;/p&gt;

&lt;p&gt;Historically the CMS system was more the domain of large enterprise organizations: hospitals, insurance companies, CPG manufacturers, car companies, etc. Part of the reason for this was the ability to keep a tight control on both the data layer, but also the look and feel of the view layer.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Nr0BRb9d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5lzogkiz7openiyr7sz6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Nr0BRb9d--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5lzogkiz7openiyr7sz6.jpg" alt="Image description" width="880" height="429"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;image source: Netsource&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In a traditional CMS stack the view layer is separate, but tied to the back-end systems that deliver data it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gDUjztlz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e7pg4km1nl0uh1gmxsnp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gDUjztlz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e7pg4km1nl0uh1gmxsnp.jpg" alt="Image description" width="880" height="822"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In headless architecture, however, each element of the CMS Stack is its own service. &lt;/p&gt;

&lt;h2&gt;
  
  
  Who cares about separation of concerns?
&lt;/h2&gt;

&lt;p&gt;I do! &lt;br&gt;
Headless architecture means that we can disperse our CMS and Front-end systems across the cloud, giving us better reliability and easier access.&lt;/p&gt;

&lt;p&gt;More than that, separation of concerns let's us parallel-thread the development process: the front-end team can be making pixel perfect React shopping cart component, while the back-end team can finish up credit card authorization integration. If they had a good architect keeping them in sync, they will both be able to just ensure their API end-points are the same and integration should be a simple process.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is headless first CMS?
&lt;/h2&gt;

&lt;p&gt;In a headless first CMS data and it's delivery end-points are the single source of truth. By creating a flexible data structure the ability to create custom API end-points to serve a variety of platforms becomes the focal point.&lt;/p&gt;

&lt;p&gt;By organizing your offering around the data you are working with, you have the ability to dip in and out of design trends and deployment platforms as the business needs dictate. &lt;/p&gt;

&lt;h2&gt;
  
  
  Use Cases?
&lt;/h2&gt;

&lt;p&gt;In my experience with medium to small marketing clients in marketing and arts, the ability to create a single piece of content, and then massage it for a number of different platforms is critical.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use case 1: Dance Company Marketing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;The Rival Tribe dance company is about to present their evening length ballet, and needs to put a strategic marketing plan in place.&lt;/strong&gt;&lt;br&gt;
They have a front-end website (React let's say), Social media channels and a scheduling app, a CRM for data collection (maybe Hubspot?), and an email campaign service (like Mailchimp). &lt;br&gt;
Each of these delivery channels has a different format, different copy needs, and especially different media formatting needs.&lt;br&gt;
If Rival Tribe is using a headless CMS with custom built integrations, they will be able to easily create content on the CMS and deliver it via API to their website, create and send a custom email campaign, and integrate it with their email list. All of this is possible because the marketing material - the data source of truth - is coming from the custom CMS API. &lt;/p&gt;

&lt;h3&gt;
  
  
  Use case 2: Point of Sale and Event Marketing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Motorsports Experience Inc., a motor sports event production company, works with a variety of athlete and racing industry influencers to promote events. They need to find a way to deliver that video content to new audiences.&lt;/strong&gt;*&lt;/p&gt;

&lt;p&gt;We live in a world of screens, and Motorsports Experience Inc wants to have their promotional content on all of them - but for now, they will settle for the video screens at gas-station pumps. It goes straight to an audience who is interacting their product (vehicles) and it will have a high impact because it's a captive audience (in spite of how much we all loathe those screens). But, how do they get their mainly social media content, onto those screens?&lt;/p&gt;

&lt;p&gt;Enter the headless CMS API: Motorsports Experience Inc., has been using a CMS to keep their influencer campaigns organized. Thankfully once the campaigns are built in the CMS, custom fields or custom end-points can be added as need to support delivery. &lt;/p&gt;

&lt;p&gt;What this means is that the legal department will spend more time hammering out agreements than the developers will spent creating data delivery methods. &lt;/p&gt;

&lt;h2&gt;
  
  
  I like big orchestras
&lt;/h2&gt;

&lt;p&gt;There is a real beauty in the way complex systems interact with themselves and the systems around them. Monolithic architecture was fine for tight control, but headless allows for more creativity and the introduction of new services without traditional pains of spinning them up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Coda
&lt;/h2&gt;

&lt;p&gt;As always, if you see something wrong here let me know - we can always do better!&lt;/p&gt;

</description>
      <category>headlesscms</category>
      <category>devops</category>
      <category>strapi</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Using Javascript to fix Wordpress annoyances in a wordpress-y way</title>
      <dc:creator>hariseldon27</dc:creator>
      <pubDate>Mon, 04 Apr 2022 23:14:51 +0000</pubDate>
      <link>https://dev.to/hariseldon27/using-javascript-to-fix-wordpress-annoyances-in-a-wordpress-y-way-4ijl</link>
      <guid>https://dev.to/hariseldon27/using-javascript-to-fix-wordpress-annoyances-in-a-wordpress-y-way-4ijl</guid>
      <description>&lt;p&gt;This post was originally titled: "Give up on platforms, not users: or why Javascript gives me hope"&lt;/p&gt;

&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@jimmyjin?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Jimmy Jin&lt;/a&gt; on &lt;a href="https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Wordpress: Whoas &amp;amp; Woes
&lt;/h2&gt;

&lt;p&gt;I started my professional journey in the tech world as a content manager for a Wordpress site.  This gave me lots of opportunities to see how fragile and cumbersome Wordpress can be. But, way back in 2009 in a pre-Squarespace world it was a good way for a Liberal Arts kid without a ton of code skills to put together a decent looking website with lots of functionality. &lt;/p&gt;

&lt;p&gt;Ever since I started to learn about Wordpress, especially its quirks and frustrations, I've been wanting a more stable solution for myself and my clients. But, as we all know change takes time.&lt;/p&gt;

&lt;p&gt;As I headed into the final four weeks of the Flatiron School Software Engineering Bootcamp I was contacted by a long time client for some adjustments and additions to her Wordpress site.&lt;/p&gt;

&lt;p&gt;The client is a journalist, we update content every few weeks, depending on her work load.  The site is simple, based on a commercial theme, and rather minimal.  As such, it doesn't allow for multiple authors to be listed on one post; and modifying the theme files (even child themes) always leads to update issues.&lt;/p&gt;

&lt;p&gt;Well, back in February she co-wrote a Washington Post article which required we place four authors on the by-line.&lt;/p&gt;

&lt;p&gt;During my time at Flatiron my minimal amount of client work occurs on weekends, preferably Saturday morning over coffee. Which means, about the last thing I want to do is build a new Wordpress theme feature.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Annoyance.&lt;br&gt;&lt;br&gt;
Frustration.&lt;br&gt;&lt;br&gt;
Desire to tear the beating heart out of the Wordpress core. &lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Vanilla Javascript to the rescue
&lt;/h2&gt;

&lt;p&gt;I finished my coffee while uploading new stories, and it occurred to me: I made this site, so I can break it!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I made this site, so I can break it&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In truth, I realized that nothing is sacred and sometimes a job done is better than a job done perfectly. With this new found freedom I opted to combine a &lt;a href="https://www.wpbeginner.com/opinion/how-many-wordpress-plugins-should-you-install-on-your-site/" rel="noopener noreferrer"&gt;very Wordpress-y&lt;/a&gt; solution, with a Javscript solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wordpress Plugins are the worst
&lt;/h2&gt;

&lt;p&gt;In spite of this ^ being true, they are still an important part of the Wordpress ecosystem. I opted for one that would let me just inject custom Javscript or CSS into the footer. Since this client is on a GoDaddy shared hosting (I know, I know...) it's a royal pain to edit theme files safely in production.  Thus, a plugin.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://wordpress.org/plugins/custom-css-js/" rel="noopener noreferrer"&gt;Simple Custom CSS/JS&lt;/a&gt; is a pretty simple plugin, and it offers an easy way to just inject JS into the footer or header. &lt;/p&gt;

&lt;p&gt;Okay, so now that we've got a tiny window into mucking about with the theme how can we add 4 author names instead of just one?&lt;/p&gt;

&lt;h2&gt;
  
  
  As simple as .append and .prepend
&lt;/h2&gt;

&lt;p&gt;In order to make our adjustment we needed to first find the place where it should be injected. The top-matter where the Author attribution in our post looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;aside&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"post-author"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;em&amp;gt;&lt;/span&gt;by&lt;span class="nt"&gt;&amp;lt;/em&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;itemprop=&lt;/span&gt;&lt;span class="s"&gt;"author"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/author-bio"&lt;/span&gt; &lt;span class="na"&gt;title=&lt;/span&gt;&lt;span class="s"&gt;"Posts by Author"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      Author Name
    &lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/aside&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt; sure looks like a good element for us to target! What if we target &lt;code&gt;.post-author span&lt;/code&gt; ? that should get us to the right spot, then we can add in some new elements dynamically.&lt;/p&gt;

&lt;p&gt;So, if our Javascript looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authorSpan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.post-author span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newspan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;authorSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prepend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newspan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That connects us to the element in the HTML, and then creates a new span, and appends that span next to our author text. Now, we just need to set the text of the span we created to the text we want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authorSpan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.post-author span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newspan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;authorSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prepend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newspan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;newspan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; Awesome Author, Rad Reader, Sweet Signature&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stick that into the plugin, and boom!  You are pretty much all set! Well, except for the fact that it'll do that to &lt;strong&gt;every single post&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft6bnikwi03sbfjjt7z1o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ft6bnikwi03sbfjjt7z1o.png" alt="screenshot of Simple Custom CSS/JS plugin"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that the plugin just injects site-wide. Hmm, if only there was a way for us to target just just that post, and just that span. &lt;/p&gt;

&lt;h2&gt;
  
  
  Thank goodness for Wordpress permalinks
&lt;/h2&gt;

&lt;p&gt;Yeah, the permalink setup can be a pain at times - but it's helpful in this case!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;pathname&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/2022/02/20/post-name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;authorSpan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.post-author span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newspan&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;authorSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;prepend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;newspan&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;newspan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerText&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt; Awesome Author, Rad Reader, Sweet Signature&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Much better - a tiny bit of conditional rendering based on the URL.  Now, after GoDaddy finally clears our cache we can see that the site is cleared of extra authors, and the post we wanted to touch up is looking smart!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Wordpress stinks, if you're here you know that. But, it's been around for a long time and was an entry way for many of us! Thankfully, even just a little code knowledge can make a huge difference in the development process.&lt;/p&gt;




&lt;p&gt;my code coda&lt;br&gt;
1) Thanks for reading, if I got something wrong let me know!&lt;/p&gt;

&lt;p&gt;2) There are always things to improve - what could we do better here?&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>wordpress</category>
      <category>plugins</category>
      <category>yuck</category>
    </item>
    <item>
      <title>ActiveRecord Dependent Options</title>
      <dc:creator>hariseldon27</dc:creator>
      <pubDate>Tue, 22 Mar 2022 13:49:39 +0000</pubDate>
      <link>https://dev.to/hariseldon27/activerecord-dependent-options-1pk3</link>
      <guid>https://dev.to/hariseldon27/activerecord-dependent-options-1pk3</guid>
      <description>&lt;p&gt;Header image by &lt;a href="https://unsplash.com/@lightscape?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Lightscape&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/happy-hour?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Validations, Relational Databases, Happiness and Fulfillment
&lt;/h2&gt;

&lt;p&gt;So you're having a hot and heavy time with your ActiveRecord backed app, Hot Hot Happy Hour, the newest Happy Hour gathering planning app: everything is coming up Martini's and Rosé: all your tables have clean data, nothing is null, and you haven't had any lost records, yet!&lt;/p&gt;

&lt;p&gt;But, what if your product manager comes to you saying, &lt;br&gt;
"We need a new feature that will let the hosts of Hot Hot Happy Hours back out after they made the event. We keep having hosts get cold feet and delete their accounts after they get a big crowd signed up for the event!  Currently, events are deleted if the host deletes their account!  We need to have the events stay online even if the host deletes their account!  That's easy enough, right?"&lt;/p&gt;

&lt;p&gt;Easy enough...right.&lt;/p&gt;

&lt;p&gt;Well, actually - it might be!  Especially if you're currently connecting the join table of the Happy Hour &lt;em&gt;Event&lt;/em&gt; records with the users table and employing &lt;code&gt;dependent: :destroy&lt;/code&gt; to ensure that if a host backs out, or deletes their account that the event itself gets removed.&lt;/p&gt;

&lt;h2&gt;
  
  
  ActiveRecord associations - with great power...
&lt;/h2&gt;

&lt;p&gt;ActiveRecord associations create so many powerful connections that we need to ensure we are handling it all correctly. Ensuring data tied to another piece of data, such as our Hot Hot Happy Hour &lt;em&gt;events&lt;/em&gt; being tied to our event hosts and users, means that when one piece of data is manipulated or destroyed, the associated data should similarly be.  &lt;a href="https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#module-ActiveRecord::Associations::ClassMethods-label-Deleting+from+associations" rel="noopener noreferrer"&gt;The Rails docs&lt;/a&gt; say: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;has_many&lt;/code&gt;, &lt;code&gt;has_one&lt;/code&gt;, and &lt;code&gt;belongs_to&lt;/code&gt; associations support the &lt;code&gt;:dependent&lt;/code&gt; option. This allows you to specify that associated records should be deleted when the owner is deleted.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Our ERD...
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F80xztjwpp478l9x4l66g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F80xztjwpp478l9x4l66g.png" alt="An entity relationship diagram showing three database tables and their connections"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is the  &lt;code&gt;:dependent&lt;/code&gt; option?
&lt;/h2&gt;

&lt;p&gt;Rails provides a nice option for handling the removal of associated data with the &lt;code&gt;:dependent&lt;/code&gt; option.  According to the &lt;a href="https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Options" rel="noopener noreferrer"&gt;Rails documentation the &lt;code&gt;:dependent&lt;/code&gt; option&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Controls what happens to the associated objects when their owner is destroyed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We are currently implementing this as such&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 ruby
class Hot_Hot_User &amp;lt; ApplicationRecord
   has_many :hot_hot_events, dependent: :destroy
end


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So, in our case with Hot Hot Happy Hour we potentially have users who are creating an event in the join table, then deleting their accounts after the event has gotten too big.  &lt;/p&gt;

&lt;p&gt;Because we are using &lt;code&gt;dependent: :destroy&lt;/code&gt;, when the user deletes their account it also deletes the associated data with it - including any events they have created, but haven't happened yet.  Big bummer for the Hot Hot Happy Hour community.&lt;/p&gt;

&lt;h2&gt;
  
  
  Options to the rescue!
&lt;/h2&gt;

&lt;p&gt;Something cool about Rails and ActiveRecord is that is offers a seriously robust set of tools to handle errors and validations.  The &lt;code&gt;:dependent&lt;/code&gt; option feels like just such a tool!&lt;/p&gt;

&lt;p&gt;In our case we don't want to destroy the events immediately, in fact we'd prefer they stay around and we can just replace the host. Heck, maybe we could automate an invitation out the most active users who are associated with that event to be the new host! Assuming we like the course of automation, let's use this idea as our guiding star and see what our options are.&lt;/p&gt;




&lt;h3&gt;
  
  
  The options &lt;code&gt;:dependent&lt;/code&gt; offers our associated data!
&lt;/h3&gt;

&lt;p&gt;Borrowed directly from the &lt;a href="https://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many-label-Deleting-from-associations" rel="noopener noreferrer"&gt;Rails Documentation:&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;nil&lt;/strong&gt; do nothing (default).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;:destroy&lt;/strong&gt; causes all the associated objects to also be destroyed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;:destroy_async&lt;/strong&gt; destroys all the associated objects in a background job. WARNING: Do not use this option if the association is backed by foreign key constraints in your database. The foreign key constraint actions will occur inside the same transaction that deletes its owner.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;:delete_all&lt;/strong&gt; causes all the associated objects to be deleted directly from the database (so callbacks will not be executed).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;:nullify&lt;/strong&gt; causes the foreign keys to be set to NULL. Polymorphic type will also be nullified on polymorphic associations. Callbacks are not executed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;:restrict_with_exception&lt;/strong&gt; causes an ActiveRecord::DeleteRestrictionError exception to be raised if there are any associated records.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;:restrict_with_error&lt;/strong&gt; causes an error to be added to the owner if there are any associated objects.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;




&lt;p&gt;To reiterate: we want an option that will allow our app to quietly have an error, then handle it with some cool new feature...darn that Product Manager and their good ideas...&lt;/p&gt;

&lt;p&gt;Looks like there are a few ways we could go about this. &lt;/p&gt;

&lt;h2&gt;
  
  
  ActiveRecord &amp;amp; Rails as safety net
&lt;/h2&gt;

&lt;p&gt;I'm a big fan of options.  I'm also a big fan of best practices...and when you're first getting started more options can make it harder to establish and follow best practices.  But, hopefully we'll be able to find a happy middle ground here.&lt;/p&gt;

&lt;p&gt;Remember, our goal is to remove a record that has data associated with it while leaving the associated data in place and capable of being further manipulated.  &lt;/p&gt;

&lt;p&gt;Let's look at the options and do a bit of psuedo-code!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;nil&lt;/strong&gt; &lt;em&gt;do nothing&lt;/em&gt; - this is the default if no option is specified. &lt;br&gt;
&lt;strong&gt;Use Case:&lt;/strong&gt; Host user deletes account, but event still exists, so no one is there to raise the first glass - or ensure that the bartenders don't stink.  This will negatively impact users.  And probably have other consequences such as error handling and further validation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;:destroy&lt;/strong&gt; &lt;em&gt;remove all associated data with the &lt;code&gt;:destroy&lt;/code&gt; command, running callbacks as needed&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;:nullify&lt;/strong&gt; &lt;em&gt;sets associated fields to null&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;Use Case:&lt;/strong&gt; I like this as an option, gives us a clear reference - and if we have a helper function that runs on a regular basis to flag any &lt;code&gt;null&lt;/code&gt; fields in the db - even better! &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;:restrict_with_exception&lt;/strong&gt; &lt;em&gt;causes an ActiveRecord::DeleteRestrictionError exception&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;Use Case:&lt;/strong&gt; this seems pretty helpful, we could use that error to automatically flag that we need a new host and instead of deleting the event, maybe it locks new users for RSVPing until a new host is associated with the event.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;:restrict_with_error&lt;/strong&gt; &lt;em&gt;causes an error to be added to the owner if there are any associated objects&lt;/em&gt;&lt;br&gt;
&lt;strong&gt;Use Case:&lt;/strong&gt; could also offer an avenue of escape, but may be more useful in the generation and handling of messages than in automating the replacement of our event host.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Keep it hot
&lt;/h2&gt;

&lt;p&gt;The reason all your users love Hot Hot Happy Hour so much is that the events are all liminal experiences beyond what humans thought possible. Which is why creating an event, and then having it cancelled at the last minute is such a bummer.  You never know when your last minute will be.  &lt;/p&gt;

&lt;p&gt;Can we devise a plan to save our events?  &lt;/p&gt;

&lt;p&gt;Our new model might look like this:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Hot_Hot_User&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;ApplicationRecord&lt;/span&gt;
   &lt;span class="n"&gt;has_many&lt;/span&gt; &lt;span class="ss"&gt;:hot_hot_events&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;dependent: :nullify&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;My approach to start would be to go with &lt;code&gt;:nullify&lt;/code&gt; and then create a helper function to alert our Customer Service department that an event lost its host. This can then allow a new host to be chosen from the currently available list of participants.  If the event host is &lt;code&gt;null&lt;/code&gt; it should still be accessible in the database, and all the rest of the data should be intact and healthy.  Once we replace the single &lt;code&gt;null&lt;/code&gt; field with a new host, we should be good to go!&lt;/p&gt;

&lt;p&gt;Lost data is nothing to shrug off, and good validations can make your life much easier!  So - keep that data clean kids, and make sure to tie your shoe laces.&lt;/p&gt;




&lt;p&gt;my code coda&lt;br&gt;
1) Thanks for reading, if I got something wrong let me know!&lt;/p&gt;

&lt;p&gt;2) There are always things to improve - what could we do better here?&lt;/p&gt;

</description>
      <category>activerecord</category>
      <category>ruby</category>
      <category>database</category>
      <category>associations</category>
    </item>
    <item>
      <title>.localeCompare() and sorting in Javascript</title>
      <dc:creator>hariseldon27</dc:creator>
      <pubDate>Wed, 23 Feb 2022 23:04:13 +0000</pubDate>
      <link>https://dev.to/hariseldon27/localecompare-and-sorting-in-javascript-1god</link>
      <guid>https://dev.to/hariseldon27/localecompare-and-sorting-in-javascript-1god</guid>
      <description>&lt;p&gt;Cover art: &lt;a href="href="&gt;Brett Zeck&lt;/a&gt; on &lt;a href="href="&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This blog post is about sorting things in Javascript, simple things like arrays or objects.  This isn't about Big-O, complex algorithmic sorting, or anything more than we can test out in the terminal with node.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Why write about sorting
&lt;/h2&gt;

&lt;p&gt;Sorting is one of those fundamental functions of front end design that is so ubiquitous that it's easy to overlook. I realized I wasn't sure how to best sort a simple set of data while the user waits, so I decided I'd make some practical notes on tackling simple sorting tasks in Javascript. Then I took it a step further and went down a rabbit hole, and here we both are.  Welcome!&lt;/p&gt;

&lt;h2&gt;
  
  
  What else is out there?
&lt;/h2&gt;

&lt;p&gt;Did you get here by way of search results?  Nicely done! I doubt this will be on the first page because there are already excellent articles out there the aspects of &lt;code&gt;.sort()&lt;/code&gt; a good place to start - as always - is &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort"&gt;MDN.&lt;/a&gt; &lt;/p&gt;

&lt;h3&gt;
  
  
  Some other worthy reading if this is your first stop:
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://dev.to/jenshaw/sorting-out-javascript-sort-4kbl"&gt;Sorting out Javascript Sort&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/40107588/intl-collator-and-natural-sort-with-numeric-option-sorts-incorrectly-with-decima"&gt;Why Localecompare can't deal with decimal numbers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://stackoverflow.com/questions/14677060/400x-sorting-speedup-by-switching-a-localecompareb-to-ab-1ab10"&gt;Localecompare and speed issues - collator method&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Did you leave to do some research and come back?  I bet you did. Do you have a better idea of how the standard &lt;code&gt;.sort()&lt;/code&gt; works now?&lt;/p&gt;
&lt;h2&gt;
  
  
  localeCompare and the Intl.Collator
&lt;/h2&gt;
&lt;h3&gt;
  
  
  What is &lt;code&gt;.localeCompare()&lt;/code&gt; ?
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;String.prototype.localeCompare()&lt;/strong&gt; is a method which returns a number indicating whether a reference string comes before, after, or is the same as the given string in order. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/localeCompare"&gt;MDN&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The basic syntax is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compareString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compareString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;locales&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;compareString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;locales&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What is the Intl.Collator?
&lt;/h3&gt;

&lt;p&gt;The &lt;strong&gt;Intl.Collator&lt;/strong&gt; object enables language sensitive string comparison. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator"&gt;MDN&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the purposes of this article suffice to say &lt;code&gt;.localeCompare()&lt;/code&gt; can be your entry point to the world of the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator"&gt;&lt;code&gt;Intl.Collator&lt;/code&gt;&lt;/a&gt; - there is cool stuff in there.&lt;/p&gt;

&lt;p&gt;The collator allows for specific language and character set variations (locales).  [see note 1 below]&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's that mean for sorting?&lt;/strong&gt; Well, it lets us sort strings and take into account language and character set variations. Let's look at a couple examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Default Sorting
&lt;/h2&gt;

&lt;p&gt;First, remember that the standard string sorting functions evaluate based on unicode values, and sort based on those.  So - let's look at those too:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Char&lt;/th&gt;
&lt;th&gt;Unicode&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;a&lt;/td&gt;
&lt;td&gt;0061&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;A&lt;/td&gt;
&lt;td&gt;0041&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ä&lt;/td&gt;
&lt;td&gt;0228&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;n&lt;/td&gt;
&lt;td&gt;006E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;004E&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ñ&lt;/td&gt;
&lt;td&gt;00F1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Don't forget! ... capitals and lower case letters also have different unicode values. Which means an uppercase &lt;em&gt;A&lt;/em&gt; comes before &lt;em&gt;a&lt;/em&gt;, which comes before &lt;em&gt;ä&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;What happens if we use &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort"&gt;array.prototype.sort()&lt;/a&gt; on these and sort in place?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;arryA&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ä&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; [ 'a', 'A', 'ä' ]&lt;/span&gt;
&lt;span class="nx"&gt;arryA&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; [ 'A', 'a', 'ä' ]&lt;/span&gt;
&lt;span class="nx"&gt;arryN&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;n&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;N&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ñ&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; [ 'n', 'N', 'ñ' ]&lt;/span&gt;
&lt;span class="nx"&gt;arryN&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sort&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; [ 'N', 'n', 'ñ' ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can see it is simply organizing our characters by unicode value. What about making our sort a bit more...well travelled?  A bit more...sensitive to different locales...&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic alpha sort with &lt;code&gt;.localeCompare()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The construction of &lt;code&gt;.localeCompare()&lt;/code&gt; is different than &lt;code&gt;.sort()&lt;/code&gt; because it is comparing a string against another string.  Compared to &lt;code&gt;.sort()&lt;/code&gt; which sorts an array in place.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ä&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; -1&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 0&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without any options &lt;code&gt;.localeCompare()&lt;/code&gt; is doing the same as the basic sort.  Let's add in some sensitivity options:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ä&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;sensitivity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 0&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;sensitivity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 0&lt;/span&gt;
&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;sensitivity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's look at each piece of the &lt;code&gt;.localCompare()&lt;/code&gt; call and talk about what is going on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;sensitivity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;string1&lt;/code&gt; and &lt;code&gt;string2&lt;/code&gt; are our strings to compare&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;'en'&lt;/code&gt; is English, for the language set to use for our comparison&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;{sensitivity: 'base'}&lt;/code&gt; is the level of sensitivity that javascript will apply to the comparison.  &lt;code&gt;'base'&lt;/code&gt; allows for letters of the same base to be evaluated equivalently, disregarding things like umlauts or capitalization - an A is an a is an ä (in this specific case at least). There are a few other sensitivity options, &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator/Collator"&gt;see all the options here.&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Ok, so we're seeing that you can use &lt;code&gt;.localeCompare()&lt;/code&gt; to smooth out alphabetical sorting, but ... what about numbers?&lt;/p&gt;

&lt;h2&gt;
  
  
  Numbers are totally international!
&lt;/h2&gt;

&lt;p&gt;Weirdly enough, trying to use &lt;code&gt;.localeCompare()&lt;/code&gt; for numeric sorting is what send me down this road in the first place. My initial research said it wasn't possible, but what I learned is: it works, and it's pretty cool! So, why the hubbub?  Well, remember this is &lt;code&gt;String.prototype.localeCompare()&lt;/code&gt; meaning that it's really only wants to work on strings, not numbers. But, thanks to the right settings you can worry no more about having numbers in your strings (I'm thinking street addresses).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// top examples establish how the comparison works&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;b&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   
&lt;span class="c1"&gt;//=&amp;gt; -1   // "a" comes before "b"&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   
&lt;span class="c1"&gt;//=&amp;gt; -1   // "1" comes before "2"&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 0   // "1" is equal to "1"&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;0&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 1   // "2" comes before "1"&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;01&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 1   // "01" comes before "1"  // huh, that's weird&lt;/span&gt;
&lt;span class="c1"&gt;// depending on your situation this might be ok, or problematic.&lt;/span&gt;
&lt;span class="c1"&gt;//&lt;/span&gt;
&lt;span class="c1"&gt;// Add in the numeric option&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;01&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;numeric&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 0&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;11&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;11&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;numeric&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 0&lt;/span&gt;
&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;11&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;localeCompare&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;011&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="na"&gt;numeric&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="c1"&gt;//=&amp;gt; 0&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Using &lt;code&gt;.localeCompare()&lt;/code&gt; for standard string comparison works nicely, and it even works if you're mixing numbers into your strings. I know that I'll be keeping these sorting options available to me if I'm working with anything with the possibility of international addresses! &lt;/p&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/Collator"&gt;&lt;code&gt;Intl.Collator&lt;/code&gt;&lt;/a&gt; is outside of the scope of this article, but if you're working with data that needs to account for language variations I'd recommend checking it out!&lt;/p&gt;

&lt;h2&gt;
  
  
  my code coda
&lt;/h2&gt;

&lt;p&gt;1) Thanks for reading, if I got something wrong let me know!&lt;br&gt;&lt;br&gt;
2) There are always things to improve - what could we do better here?&lt;/p&gt;

&lt;h4&gt;
  
  
  notes
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;1&lt;/strong&gt; The Intl.Collator yields great performance value over using localeCompare() on its own when working with large datasets - I'd urge you take a deep dive into it if you're working with large datasets.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2&lt;/strong&gt; - in German a and ä have the same base letter, the same goes for Spanish with n and ñ - which means they evaluate to the same value with sensitivity. In languages like Swedish which have differing base letters for ä and a they are evaluated separately.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>localecompare</category>
      <category>sort</category>
      <category>array</category>
    </item>
    <item>
      <title>Custom Loading Animation on Fetch Call in Vanilla Javascript / CSS / HTML 5</title>
      <dc:creator>hariseldon27</dc:creator>
      <pubDate>Mon, 07 Feb 2022 14:01:34 +0000</pubDate>
      <link>https://dev.to/hariseldon27/custom-loading-animation-on-fetch-call-in-vanilla-javascript-css-html-5-1a9n</link>
      <guid>https://dev.to/hariseldon27/custom-loading-animation-on-fetch-call-in-vanilla-javascript-css-html-5-1a9n</guid>
      <description>&lt;p&gt;Do you have an API call that is sorta slow, and you want to keep your user occupied while it loads and you're not quite sure how to do it?  Well, it's easier than you'd think!  &lt;/p&gt;

&lt;h2&gt;
  
  
  Why a custom loading animation for vanilla javascript? Meh...why not?
&lt;/h2&gt;

&lt;p&gt;This blog post comes out of the project that I co-created for the first phase of the Flatiron School Software Engineer Program.  We built a game that called the Met Museum API, which was really neat! Unfortunately, it had to make 4-7 API calls per game-round to make sure it got enough clean data.  Eventually it all worked, but it took as much as 5-seconds for the API calls to return and the Dom to update.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16pmangb3igahrl0wfa1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F16pmangb3igahrl0wfa1.png" alt="An image of loading times from API calls, each time is approximately 1 second"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Seeing those gross loading times puts us in a good place to explore where to go next. &lt;/p&gt;

&lt;h2&gt;
  
  
  User Experience
&lt;/h2&gt;

&lt;p&gt;The biggest UX issue we have is that when you finish a round the game appears to be frozen while it's waiting for the new data to load.  &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;UX is more than just making things pretty - it's about making the experience more responsive to the user's needs&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even though the final version of the game implements a few modal windows to occupy the user, we wanted to really cover the loading time with some branded loading animation.  As it turned out it was pretty straight forward to hook a loading animation into the asynchronous fetch call.  &lt;/p&gt;

&lt;p&gt;Now, let's be straight: there's lots of ways to implement a loading spinner - this way is fine for small special applications.  Is it what I'd use in any kind of larger deployment, even a vanilla javascript one?  No, no I probably wouldn't  But, this is a cool little trick to get things going in a single page application.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are we doing for a loading animation?
&lt;/h3&gt;

&lt;p&gt;Our loading animation is pretty simple, we're going to embed an animated SVG in a hidden div, and when we call it with Javascript it goes from hidden to visible.  Pretty easy - let's see how it's done!&lt;/p&gt;

&lt;h2&gt;
  
  
  Animated SVG in a Hidden Div
&lt;/h2&gt;

&lt;p&gt;^Sounds like the title of a Russian fairy tale.&lt;br&gt;&lt;br&gt;
So, how about that animated SVG I keep talking about, what's that all about?  Let's see:&lt;br&gt;
SVG stands for Scalable Vector Graphics, and it's basically an inbuilt vector rendering engine that is XML based.  So, what it takes to get it going is the same as everything else around here, a bit of code.&lt;/p&gt;

&lt;p&gt;Try this one below, it comes from &lt;a href="https://developer.mozilla.org/en-US/docs/Web/SVG/Element/animateMotion" rel="noopener noreferrer"&gt;Mozilla MDN&lt;/a&gt; and is a lovely example.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;

&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 200 100"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"none"&lt;/span&gt; &lt;span class="na"&gt;stroke=&lt;/span&gt;&lt;span class="s"&gt;"lightgrey"&lt;/span&gt; &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;circle&lt;/span&gt; &lt;span class="na"&gt;r=&lt;/span&gt;&lt;span class="s"&gt;"5"&lt;/span&gt; &lt;span class="na"&gt;fill=&lt;/span&gt;&lt;span class="s"&gt;"red"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;animateMotion&lt;/span&gt; &lt;span class="na"&gt;dur=&lt;/span&gt;&lt;span class="s"&gt;"10s"&lt;/span&gt; &lt;span class="na"&gt;repeatCount=&lt;/span&gt;&lt;span class="s"&gt;"indefinite"&lt;/span&gt; &lt;span class="na"&gt;path=&lt;/span&gt;&lt;span class="s"&gt;"M20,50 C20,-50 180,150 180,50 C180-50 20,150 20,50 z"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/circle&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;What the heck, let's use that as part of our example.  Put that svg into a &lt;code&gt;Div&lt;/code&gt; at the bottom of your body section, set it to &lt;code&gt;display:none&lt;/code&gt; and then set a few more options to get the background to cover the page.  And the easy way to do it is to simply change the &lt;code&gt;display: none&lt;/code&gt; to a &lt;code&gt;display: block&lt;/code&gt; (or whatever you need) when the right moment occurs in your script.  &lt;/p&gt;

&lt;p&gt;See it in action on repl.it here:&lt;br&gt;
&lt;/p&gt;
&lt;div class="ltag__replit"&gt;
  &lt;iframe height="550px" src="https://repl.it/@hariseldon27/Vanilla-JS-Spinner-in-Hidden-Div?lite=true"&gt;&lt;/iframe&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  Hooking it to the Fetch Request
&lt;/h2&gt;

&lt;p&gt;Yeah yeah yeah - okay we get it - it's easy as pie to make a hidden div appear.  And yeah, we get it - maybe it isn't the cleanest way to do it, but if when push comes to shove and you can only have one file it's a worthwhile tool to have around.&lt;/p&gt;

&lt;p&gt;So how do we go about hooking the appearance of our cool new loading animation that we &lt;del&gt;stole&lt;/del&gt; borrowed from MDN?  Well, it's pretty easy actually.  But, it's worth talking a little about about how to ensure you are making an asynchronous fetch request first.&lt;/p&gt;

&lt;h2&gt;
  
  
  Async Await / Fetch - a toast to the happy couple
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/29wik0hT7Ck9jppi6D/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/29wik0hT7Ck9jppi6D/giphy.gif" alt="animated gif of two champagne glasses clinking in a toast"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In order to improve the user experience of sites that rely on calls to servers or APIs for information, Javascript gives us a neat way to manage what code is running when. &lt;/p&gt;

&lt;p&gt;Under normal circumstances our code runs in more or less a linear fashion in Javascript - aside from neat features like function hoisting and scope.  However, we can ask Javascript to treat a function asynchronously from the other code that it's being asked to execute.  This also means we can ask other functions to await that asynchronous code to finish before it tries to complete its task.  We will make use of this in our fetch call, especially with our loader in mind.&lt;/p&gt;

&lt;p&gt;To move your fetch function into the asynchronous pile put &lt;code&gt;async&lt;/code&gt; before the function declaration like so:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

 &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;goFetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;apiurl.com/endpoint&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;resp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
   &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Then in our callback function we can simply remind it that it needs to &lt;code&gt;await&lt;/code&gt; that fetch to complete before it tries to run.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;doSomething&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;So where do we hook in the loading animation?  Well, we've already got our fancy-schmancy show/hide functions in JS if you remember.  &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;loadingDiv&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;loading&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;loadingDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addEventListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;click&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;hideSpinner&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;showSpinner&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;loadingDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;block&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;hideSpinner&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;loadingDiv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;display&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;none&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Those &lt;code&gt;showSpinner()&lt;/code&gt; and &lt;code&gt;hideSpinner()&lt;/code&gt; functions can just go at the points where it makes sense: &lt;strong&gt;show it right after the fetch, and hide it right after we finish populating the dom with data.&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;In our Met Guess game we fire the &lt;code&gt;showSpinner()&lt;/code&gt; function right after our very first fetch request, and we don't run the &lt;code&gt;hideSpinner()&lt;/code&gt; function until after the API returns data.  What could we have done better?  Well, look at the console logs and see if you can guess!  If you said, have the spinner appear immediately and then stay up until the DOM render completed, you're right...always room for improvement around here!&lt;/p&gt;

&lt;p&gt;See that cool codepen here:&lt;br&gt;
&lt;iframe height="600" src="https://codepen.io/HariSeldon27/embed/PoOwwjp?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post we've talked about why we might want to use a loading animation, we looked at one sorta janky way to implement it, and more importantly we looked at a way to hook your loading animation into the fetch call of your Javascript.  &lt;/p&gt;

&lt;p&gt;Have questions?  Me too!  Let's talk. &lt;/p&gt;

&lt;p&gt;I respond to any and all responses!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>html</category>
      <category>animatedsvg</category>
    </item>
    <item>
      <title>Starting Week 1</title>
      <dc:creator>hariseldon27</dc:creator>
      <pubDate>Tue, 18 Jan 2022 16:41:16 +0000</pubDate>
      <link>https://dev.to/hariseldon27/starting-week-1-442o</link>
      <guid>https://dev.to/hariseldon27/starting-week-1-442o</guid>
      <description>&lt;p&gt;What a week!  After living my whole life around code, today marks the first seven days of actually dedicating time and resources to learning code full time.  It is exhausting.&lt;/p&gt;

&lt;p&gt;I'm loving every console.log('Hello World') and fetch request. Week one of the 15 week Flatiron Software Engineering course got me through DOM manipulation and JSON parsing. &lt;/p&gt;

&lt;p&gt;Finishing week 1 on JSON data felt like a good place: there is something magical about a nicely formatted data set. &lt;/p&gt;

&lt;p&gt;I expect that I'll have more data-related posts in the future, for now I'll leave with something I was thinking about while walking the dog this weekend:&lt;/p&gt;

&lt;p&gt;Array and frame of reference within in a delimited space: If we are shifting and unshifting data around in an array, in relationship a single piece of data what are we doing?  Are we moving the data around within the array, or are we shifting the array's frame of reference. This question arises for me when thinking about shifting data around in an array as if it were a playing board (tetris or chess for example).  If I move a piece one slot left, is the piece moving or are we moving the whole frame of reference for the array.  &lt;/p&gt;

&lt;p&gt;Would a more efficient way would be to swap positions for the data with the element next to it rather than actually moving all the data around it?&lt;/p&gt;

&lt;p&gt;More to come, specific examples.  For now, on to week 2 and our first code challenge.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>beginners</category>
      <category>flatiron</category>
    </item>
    <item>
      <title>New beginnings</title>
      <dc:creator>hariseldon27</dc:creator>
      <pubDate>Mon, 10 Jan 2022 05:15:35 +0000</pubDate>
      <link>https://dev.to/hariseldon27/new-beginnings-5egh</link>
      <guid>https://dev.to/hariseldon27/new-beginnings-5egh</guid>
      <description>&lt;h2&gt;Twilight on the start of the next chapter&lt;/h2&gt;

&lt;p&gt;It's 8:50pm on Sunday January 9th, 2022.  Tomorrow I am starting  the Flatiron full time 15-week Software Engineering intensive program.  I'm both excited and nervous - as one would expect. I'm genuinely excited to be diving in and learning some new languages.  I think what I'm most excited about is the chance to put some of the more academic logic that I've learned to work in a formal programming setting.  That is very very appealing to me.  Abstraction has always sort of been my thing any way...&lt;/p&gt;

&lt;h2&gt;Humble Beginnings&lt;/h2&gt;

&lt;p&gt;It's weird to think that I've literally been around computers for as long as I can remember.  Before it was normal to have a computer in your room, I had a huge hulking box humming away in the corner of my childhood bedroom.  We flirted with 386's and 486's as kiddos, and by the time I was in high school it was Pentium's and the sinking too much money into video cards. It feels like a shocking oversight that I haven't seriously tried to get into tech previously.&lt;/p&gt;

&lt;h2&gt;Honest Goals&lt;/h2&gt;

&lt;p&gt;Since I really don't know what to expect out of the coming weeks and months I can't really set any specific goals, but I do want to be true to my career thus far: to keep exploring storytelling through new media; to be professional and expect the best of your colleagues; and to create space in projects to hold up the unique experiences of my collaborators.  &lt;/p&gt;

&lt;h2&gt;Here we go&lt;/h2&gt;

&lt;p&gt;It's been a sort of wacky few years, with lots of false starts. I truly hope that this isn't another one.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>bootcamp</category>
      <category>flatiron</category>
      <category>nontech</category>
    </item>
  </channel>
</rss>
