<?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: Corey Ward</title>
    <description>The latest articles on DEV Community by Corey Ward (@coreyward).</description>
    <link>https://dev.to/coreyward</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%2F343920%2Fb364d472-ecd4-4bfc-b32a-e9852be3345a.jpeg</url>
      <title>DEV Community: Corey Ward</title>
      <link>https://dev.to/coreyward</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/coreyward"/>
    <language>en</language>
    <item>
      <title>Case Sensitivity with `localeCompare` in JavaScript</title>
      <dc:creator>Corey Ward</dc:creator>
      <pubDate>Fri, 22 Sep 2023 20:03:19 +0000</pubDate>
      <link>https://dev.to/coreyward/case-sensitivity-with-localecompare-in-javascript-4c0o</link>
      <guid>https://dev.to/coreyward/case-sensitivity-with-localecompare-in-javascript-4c0o</guid>
      <description>&lt;p&gt;I recently ran into a bug using code like the following:&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;someArray&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="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&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;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At a glance this seems fine—&lt;code&gt;localCompare&lt;/code&gt; enjoys fantastic browser support, and as the name suggests, it isn’t English-centric. However, this is still the web we’re building for, and the familiar gotcha of inconsistent behavior amongst browsers is lurking here. This can lead to hard-to-debug inconsistencies and bugs.&lt;/p&gt;

&lt;p&gt;Most browsers—including Chrome, Edge, and Firefox—and Node treat &lt;code&gt;localeCompare&lt;/code&gt; as case-insensitive by default, treating an uppercase “A” as the same as a lowercase “a”. Safari, however, does something different.&lt;/p&gt;

&lt;p&gt;Safari uses a variant of case-sensitive sorting, but not in the usual ASCII order where “Z” sorts above “a”. Instead Safari sorts lowercase letters above their uppercase companions, but in alphabetical order otherwise, like “aAbBcC”. In many cases this is fine—sorting based on the user’s locale is not only acceptable, it’s preferable. But as you may suspect given the title, &lt;strong&gt;that’s not always true&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In scenarios where data is expected to match the order from a server, such as when sorting properties before hashing for verification or as a checksum, or when hydrating server-side rendered React, this behavior becomes troublesome. In these cases, consistent behavior across environments is critical to prevent bugs. Thankfully, this can be achieved by specifying a few additional options to &lt;code&gt;localeCompare&lt;/code&gt;:&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;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&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;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&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="s2"&gt;base&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;First, we’re specifying an expected locale. This ensures the items are compared in the same locale server-side and client-side. In a localized app, this value can be localized as well, just be sure to use the same value in both environments.&lt;/p&gt;

&lt;p&gt;The second change, adding &lt;code&gt;sensitivity: "base"&lt;/code&gt;, tells browsers to use the &lt;em&gt;base&lt;/em&gt; character (think lowercase) for comparison (MDN), effectively making the comparison case-insensitive. This results in consistent sorting behavior across Node and all common browsers (including IE11). 🎉&lt;/p&gt;

</description>
      <category>i18n</category>
      <category>react</category>
      <category>sort</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Use Neon.tech Postgres as a Segment Data Warehouse</title>
      <dc:creator>Corey Ward</dc:creator>
      <pubDate>Fri, 22 Sep 2023 16:50:48 +0000</pubDate>
      <link>https://dev.to/coreyward/use-neontech-postgres-as-a-segment-data-warehouse-3n0e</link>
      <guid>https://dev.to/coreyward/use-neontech-postgres-as-a-segment-data-warehouse-3n0e</guid>
      <description>&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; At the time I wrote this, Neon had very different pricing that allowed you to pay as you go for storage and compute, all starting at $0. They have since switched to a pricing model that does not allow you to scale storage without paying $69/mo (base price). They also have a terrible track record for uptime. I have since switched to Supabase for scalable Postgres hosting, and I recommend anybody considering Neon look at alternatives instead.&lt;/p&gt;




&lt;p&gt;Segment allows users to connect a Postgres database as a data warehouse. Officially they only support Heroku, who seems to be on its way out, and AWS RedShift, which has rather complex pricing and a more limited feature set than a standard Postgres install. Unofficially, though, the service works with any standard, modern Postgres install. &lt;/p&gt;

&lt;p&gt;Neon is a serverless-oriented provider of hosted, managed Postgres databases that scale automatically based on usage. It's convenient, and because you don't have to commit to a storage tier and worry about complicated processes for upgrading to larger instances, it winds up priced in a compelling manner.&lt;/p&gt;

&lt;p&gt;Connecting Segment to Neon is a mostly straightforward affair, but because Segment doesn't support SNI-based TLS on Postgres connections, Neon needs a bit of additional information to know which endpoint is being connected to. Usually it's sufficient to add this information to the connection string, but Segment insists on having all of the values broken up and fails if you modify the hostname to include a path or query string. Thankfully, Neon has a multitude of ways to specify the endpoint, including one that works with Postgres.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connecting to Neon PG from Segment
&lt;/h3&gt;

&lt;p&gt;In the Segment interface, create a new Postgres data warehouse. Be sure to choose "Destination" connection and not the "Source" version. Choose a source as desired, and then you'll get brought to the connection details screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F778kooqxv45fkwo539lq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F778kooqxv45fkwo539lq.png" alt="Connection details screen" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From here you'll enter most of the values copied from your Neon connection string, but when you get to the &lt;strong&gt;password&lt;/strong&gt; field you'll need to make a change. Instead of entering the password as-is, you'll prefix it with a configuration flag specifying the endpoint, like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;endpoint=&amp;lt;endpoint-id&amp;gt;;&amp;lt;password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The endpoint ID is the first-listed (leftmost) subdomain in the hostname. For example, if your full hostname is &lt;code&gt;ep-fun-coding-94135731.us-east-2.aws.neon.tech&lt;/code&gt;, the endpoint ID is &lt;code&gt;ep-fun-coding-94135731&lt;/code&gt;. If your password is &lt;code&gt;abcd1234&lt;/code&gt;, your final value for the password-field would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;endpoint=endpoint=ep-fun-coding-94135731;abcd1234
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Plug that in and you'll get something like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc1n6iugyvym02znt1nlz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc1n6iugyvym02znt1nlz.png" alt="connection settings with credentials in place" width="800" height="637"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click "Connect" and you should be all set!&lt;/p&gt;

</description>
      <category>postgres</category>
      <category>neon</category>
      <category>segment</category>
      <category>warehouse</category>
    </item>
  </channel>
</rss>
