<?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>Forem: Mastering JS</title>
    <description>The latest articles on Forem by Mastering JS (@masteringjs).</description>
    <link>https://forem.com/masteringjs</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%2F654783%2F52f37a3a-6b94-490d-b0f1-c6b8114ff627.png</url>
      <title>Forem: Mastering JS</title>
      <link>https://forem.com/masteringjs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/masteringjs"/>
    <language>en</language>
    <item>
      <title>How We Think About Securing Express.js APIs in 2024</title>
      <dc:creator>Mastering JS</dc:creator>
      <pubDate>Tue, 13 Aug 2024 20:10:03 +0000</pubDate>
      <link>https://forem.com/masteringjs/how-we-think-about-securing-expressjs-apis-in-2024-5h3p</link>
      <guid>https://forem.com/masteringjs/how-we-think-about-securing-expressjs-apis-in-2024-5h3p</guid>
      <description>&lt;p&gt;Securing your &lt;a href="https://masteringjs.io/express" rel="noopener noreferrer"&gt;Express.js API&lt;/a&gt; involves a lot of tradeoffs. Do you use cookies or &lt;a href="https://masteringjs.io/tutorials/axios/authorization" rel="noopener noreferrer"&gt;authorization header&lt;/a&gt;, JWT or access token? Do build your own authentication or use something like &lt;a href="https://auth0.com/" rel="noopener noreferrer"&gt;Auth0&lt;/a&gt;? Do build your own authorization or use a service like &lt;a href="https://www.osohq.com/" rel="noopener noreferrer"&gt;Oso&lt;/a&gt;? In this blog post, I'll cover how &lt;a href="https://masteringjs.io/" rel="noopener noreferrer"&gt;Mastering JS&lt;/a&gt; currently thinks about security for the numerous Express APIs we maintain.&lt;/p&gt;

&lt;h2&gt;
  
  
  Cookies vs Authorization Header
&lt;/h2&gt;

&lt;p&gt;This is admittedly somewhat controversial, but our Express APIs only support authentication via the &lt;code&gt;authorization&lt;/code&gt; header. We don't support cookies at all. The primary reason is that header-based authentication is easier to work with, both for SPA web clients and mobile apps; and we don't want to support multiple authentication strategies.&lt;/p&gt;

&lt;p&gt;Cookies, especially when combined with &lt;a href="https://masteringjs.io/tutorials/express/cors" rel="noopener noreferrer"&gt;CORS&lt;/a&gt;, are quite tricky to get right. In our experience, it is much easier to just &lt;a href="https://masteringjs.io/tutorials/axios/authorization" rel="noopener noreferrer"&gt;set an authorization header on an Axios request&lt;/a&gt; and be done with it.&lt;/p&gt;

&lt;h2&gt;
  
  
  JWT vs Access Token
&lt;/h2&gt;

&lt;p&gt;We prefer randomly generated access tokens that we store in MongoDB using an &lt;code&gt;AccessToken&lt;/code&gt; &lt;a href="https://mongoosejs.com" rel="noopener noreferrer"&gt;Mongoose&lt;/a&gt; model over &lt;a href="https://jwt.io/" rel="noopener noreferrer"&gt;JWTs&lt;/a&gt;. JWTs are faster, because you don't need a database round trip to validate a JWT.&lt;/p&gt;

&lt;p&gt;But JWTs make it difficult to forcibly log out a user. Once a JWT is generated, the JWT is usable until its expiration date, unless you either delete the user, rotate your JWT key (which logs out everyone), or store a list of disabled JWTs in your database. This makes it tricky to implement a "log me out of all devices" feature, which is important in case one of your users loses their phone or laptop.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authentication: Build vs Buy
&lt;/h2&gt;

&lt;p&gt;Historically we have been big proponents of building your own authentication. We store users and &lt;a href="https://thecodebarbarian.com/thoughts-on-user-passwords-in-rest-apis" rel="noopener noreferrer"&gt;authentication methods&lt;/a&gt; in our own database. Our primary concern with an external provider is vendor lock-in: authentication is fundamental to any app, and replacing an authentication provider is non-trivial.&lt;/p&gt;

&lt;p&gt;However, recently we've been rethinking this stance, especially if we're able to still store our user data in our own database. Authentication gets extremely tricky: setting up keys for all the different OAuth providers (Apple, &lt;a href="https://masteringjs.io/tutorials/node/google-oauth-authorized-redirect-uris" rel="noopener noreferrer"&gt;Google&lt;/a&gt;, etc.) is a tedious manual process, implementing 2FA with support for authenticator apps is non-trivial. There's just too much repetitive complexity to re-implement the same authentication logic in every single API, so we're considering switching to an authentication provider.&lt;/p&gt;

&lt;h2&gt;
  
  
  Authorization: Build vs Buy
&lt;/h2&gt;

&lt;p&gt;Like authentication (prove to the server that Bob is who he says), historically we have preferred to implement our own authorization (is Bob allowed to do what he is trying to do?). For basic role-based access control, writing your own authorization is fairly straightforward.&lt;/p&gt;

&lt;p&gt;However, like 2FA and OAuth, &lt;a href="https://www.osohq.com/docs/guides/role-based-access-control-rbac/role-based-access-control-in-nodejs" rel="noopener noreferrer"&gt;role-based access control in Node.js&lt;/a&gt; quickly becomes more complicated as business needs grow. Eventually the global "admin" role evolves into "a user has the 'admin' role on these resources", which evolves into "a user can perform an action on one resource if they have the 'admin' role on another resource."&lt;/p&gt;

&lt;p&gt;When the third case starts popping up, that's when an authorization provider like &lt;a href="https://osohq.com/" rel="noopener noreferrer"&gt;Oso&lt;/a&gt; or &lt;a href="https://permit.io/" rel="noopener noreferrer"&gt;Permit.io&lt;/a&gt; starts to sound appealing. Centralized, easily readable authorization logic combined with easy queries for "what users are allowed to perform this action?" sounds great when your authorization logic starts to get a bit too complex. And we're finding a few cases where our authorization logic is getting too hard to reason about, so we're also considering switching to an authorization provider.&lt;/p&gt;

</description>
      <category>node</category>
      <category>webdev</category>
      <category>mongodb</category>
      <category>express</category>
    </item>
    <item>
      <title>Our Recommendations for Vue App Architecture in 2022</title>
      <dc:creator>Mastering JS</dc:creator>
      <pubDate>Thu, 07 Apr 2022 15:55:31 +0000</pubDate>
      <link>https://forem.com/masteringjs/our-recommendations-for-vue-app-architecture-in-2022-5604</link>
      <guid>https://forem.com/masteringjs/our-recommendations-for-vue-app-architecture-in-2022-5604</guid>
      <description>&lt;p&gt;At Mastering JS, we're all about pragmatic web development. That means we aggressively avoid work that isn't related to shipping new features. We believe in spending &lt;a href="https://www.getrevue.co/profile/masteringjs/issues/why-you-shouldn-t-use-a-static-site-generator-for-your-next-blog-292833"&gt;at most 1 hour per quarter on build system work&lt;/a&gt; so we don't waste time bikeshedding &lt;a href="https://masteringjs.io/tutorials/webpack/config"&gt;Webpack configs&lt;/a&gt; or discussing "state management" (is that even a thing anymore?).&lt;/p&gt;

&lt;p&gt;In other words, we want to spend most of our calories writing &lt;a href="https://masteringjs.io/tutorials/vue/v-if"&gt;v-if&lt;/a&gt; and &lt;a href="https://masteringjs.io/tutorials/vue/bind"&gt;v-bind&lt;/a&gt; statements, not tinkering with our build.&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;Everything starts with an &lt;code&gt;index.html&lt;/code&gt; file that we typically host on Netlify. The &lt;code&gt;index.html&lt;/code&gt; file contains the below &lt;code&gt;body&lt;/code&gt;.&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;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"content"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/vue@3.x"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/vue-router@4.0.10"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/bundle.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We prefer to load &lt;a href="https://masteringjs.io/tutorials/vue/cdn"&gt;Vue from a CDN&lt;/a&gt; to avoid having to bundle it ourselves. Same with &lt;a href="https://masteringjs.io/tutorials/vue/router"&gt;Vue Router&lt;/a&gt;. Why? Tree shaking isn't worth it for us, because we don't put Vue on SEO-focused pages. If we want a page to rank on Google, we do vanilla JS, &lt;em&gt;unless&lt;/em&gt; the page is specifically about Vue and needs to have some interactive examples.&lt;/p&gt;

&lt;p&gt;Our bundle does contain most other dependencies, which is why we build our bundle using Webpack.&lt;/p&gt;

&lt;h2&gt;
  
  
  Webpack Config
&lt;/h2&gt;

&lt;p&gt;Below is our standard Webpack config for Vue projects.&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;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./.config&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;webpack&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;webpack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;development&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/src/main.js`&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;target&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;web&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/public`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bundle.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;optimization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;minimize&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- Remove need for source maps&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="c1"&gt;// Allow accessing config&lt;/span&gt;
    &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;webpack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;DefinePlugin&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;`__&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&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;module&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;rules&lt;/span&gt;&lt;span class="p"&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;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;html$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- Allow `require()` on HTML files&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;asset/source&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;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sr"&gt;css$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;-- Allow `require()` on CSS files&lt;/span&gt;
        &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;asset/source&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="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;3 things worth noting about this config:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We disable minification in prod. Again, the performance benefit of minifying is so negligible in our case that it isn't worth the developer time to set up source maps, etc. If minification provides a meaningful performance benefit, that means you're shipping wayyyyyyyyyy too much JavaScript and should fix your app.&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://masteringjs.io/tutorials/webpack/define-plugin"&gt;plugins&lt;/a&gt; to import config.&lt;/li&gt;
&lt;li&gt;Import HTML and CSS as strings using &lt;code&gt;type: 'asset/source'&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Why do we import HTML and CSS as strings? So we can define the HTML and CSS for our components in &lt;code&gt;.html&lt;/code&gt; and &lt;code&gt;.css&lt;/code&gt; files. For example, below is our &lt;code&gt;footer/index.js&lt;/code&gt; file:&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;use strict&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;appendCSS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../appendCSS&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;css&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./footer.css&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;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./footer.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;appendCSS&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;css&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;footer-component&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;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means all our layout work is done in HTML and CSS. No need to actually touch JavaScript. A huge win for us, because this means we can delegate most of our new layout work out to designers on Fiverr or similar services. They send us a complete layout, and we just put it into a component.&lt;/p&gt;

&lt;h2&gt;
  
  
  State
&lt;/h2&gt;

&lt;p&gt;State management is largely a non-issue in Vue. Frontend devs tend to discuss state management ad infinitum because it is a huge problem in frameworks like React, which are written for pre-ES6 JavaScript and are hopelessly out of date.&lt;/p&gt;

&lt;p&gt;For us, our top-level page components (the components we pass to Vue Router) are responsible for setting state and fetching data. To avoid prop drilling, they pass state down using &lt;a href="https://masteringjs.io/tutorials/vue/inject"&gt;Vue's &lt;code&gt;provide&lt;/code&gt; option&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Why We're Focusing on Browser Tools in 2022</title>
      <dc:creator>Mastering JS</dc:creator>
      <pubDate>Fri, 04 Mar 2022 03:11:58 +0000</pubDate>
      <link>https://forem.com/masteringjs/why-were-focusing-on-browser-tools-in-2022-4d2f</link>
      <guid>https://forem.com/masteringjs/why-were-focusing-on-browser-tools-in-2022-4d2f</guid>
      <description>&lt;p&gt;My biggest source of frustration earlier in my dev career was just how unbearably adhoc all the work was. Working at early stage startups meant constantly gluing disparate code together in unpredictable one-off ways: convert &lt;a href="https://masteringjs.io/tutorials/node/html-to-pug"&gt;HTML to Pug&lt;/a&gt; here, build a &lt;a href="https://masteringjs.io/tutorials/webpack/config"&gt;Webpack config&lt;/a&gt; to compile a special script for a client there. It was a nightmare to try to find a working npm module and figure out how to use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a Browser Tool?
&lt;/h3&gt;

&lt;p&gt;A tool that runs directly in your browser. No npm packages to install, no docs to read. Just type in Google, click link, copy/paste problem, and get solution.&lt;/p&gt;

&lt;p&gt;Web UIs are &lt;em&gt;ideally&lt;/em&gt; more intuitive, don't require installing anything, and get you from problem to solution faster.&lt;/p&gt;

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

&lt;p&gt;Browser tools aren't great when you need to solve a problem as part of an automated process. You don't want to have to copy/paste your code into a browser for tasks that you need to do repetitively, like linting and compiling. But converting some HTML you got off of Fiverr into Pug, or converting a config from &lt;a href="https://masteringjs.io/tutorials/tools/json-to-yaml"&gt;JSON to YAML&lt;/a&gt;, or converting &lt;a href="https://masteringjs.io/tutorials/fundamentals/decimal-to-binary"&gt;decimal to binary&lt;/a&gt;? We definitely prefer browser tool to CLI.&lt;/p&gt;

&lt;p&gt;The Mastering JS mantra has always been &lt;em&gt;devs solve problems by Googling&lt;/em&gt;. Browser tools help developers get from problem to solution faster using their preferred method.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenges of Building Browser Tools
&lt;/h3&gt;

&lt;p&gt;UI/UX is the primary goal. Specifically, get you from problem to solution as fast as possible, while minimizing any mental overhead. Performance is key to this goal, which is one of several reasons why we avoid adding a server component to our tools where possible. Most of the time, we can get away with just using &lt;a href="https://masteringjs.io/webpack"&gt;Webpack&lt;/a&gt; to bundle an npm package to do what we want to do.&lt;/p&gt;

&lt;p&gt;We're still learning the right UI/UX patterns, so please let us know what you think of our tools in the comments.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>3 Neat toString() Tricks in JavaScript</title>
      <dc:creator>Mastering JS</dc:creator>
      <pubDate>Mon, 17 Jan 2022 18:20:06 +0000</pubDate>
      <link>https://forem.com/masteringjs/3-neat-tostring-tricks-in-javascript-1lg9</link>
      <guid>https://forem.com/masteringjs/3-neat-tostring-tricks-in-javascript-1lg9</guid>
      <description>&lt;p&gt;Most JavaScript objects and primitive values have a &lt;a href="https://masteringjs.io/tutorials/fundamentals/tostring"&gt;&lt;code&gt;toString()&lt;/code&gt;&lt;/a&gt; function that converts the value to a string. Different values have different &lt;code&gt;toString()&lt;/code&gt; methods, and some &lt;code&gt;toString()&lt;/code&gt; methods have cool surprises. Here's 3:&lt;/p&gt;

&lt;p&gt;1) Numbers have a &lt;code&gt;toString()&lt;/code&gt; function that supports different bases&lt;/p&gt;

&lt;p&gt;Converting &lt;a href="https://masteringjs.io/tutorials/fundamentals/decimal-to-binary"&gt;decimal to binary&lt;/a&gt; in JavaScript is easy, because JavaScript numbers have a &lt;code&gt;toString()&lt;/code&gt; function that takes a &lt;code&gt;radix&lt;/code&gt; parameter that specifies which base to use.&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;let&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// '101010'&lt;/span&gt;

&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;16&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// '2a', hexadecimal!&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Encode data as base64 using &lt;a href="https://masteringjs.io/tutorials/node/buffer"&gt;Node.js Buffers&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://masteringjs.io/tutorials/node/buffer-to-string"&gt;Node buffers have a &lt;code&gt;toString()&lt;/code&gt; function&lt;/a&gt; that takes an encoding parameter. Calling &lt;code&gt;toString('base64')&lt;/code&gt; converts the buffer into a base64 string, which is handy if you need to convert a file into base64 for email attachments.&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;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&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;buf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./package.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;buf&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base64&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 'ewogICJuYW1lIjog...'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3) Custom Tags for Objects&lt;/p&gt;

&lt;p&gt;Objects' &lt;code&gt;toString()&lt;/code&gt; is not very useful by default: the output is just &lt;code&gt;[object Object]&lt;/code&gt;. However, you can make this output slightly more useful by setting the object's &lt;code&gt;Symbol.toStringTag&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;

&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toStringTag&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Test&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// '[object Test]'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
    </item>
    <item>
      <title>3 Neat Tricks For Sorting Arrays of Objects in JavaScript</title>
      <dc:creator>Mastering JS</dc:creator>
      <pubDate>Tue, 12 Oct 2021 22:45:03 +0000</pubDate>
      <link>https://forem.com/masteringjs/3-neat-tricks-for-sorting-arrays-of-objects-in-javascript-3lnb</link>
      <guid>https://forem.com/masteringjs/3-neat-tricks-for-sorting-arrays-of-objects-in-javascript-3lnb</guid>
      <description>&lt;p&gt;Working with arrays of objects in JavaScript can be a headache. &lt;a href="https://masteringjs.io/tutorials/fundamentals/compare-arrays"&gt;Comparing arrays of objects&lt;/a&gt; is tricky without libraries. But, thankfully, &lt;a href="https://masteringjs.io/tutorials/fundamentals/sort-array-of-objects"&gt;sorting arrays of objects&lt;/a&gt; is somewhat easier because of some neat tricks.&lt;/p&gt;

&lt;h2&gt;
  
  
  1) Sorting By Date Properties
&lt;/h2&gt;

&lt;p&gt;The hard part of sorting arrays of objects is to compare objects &lt;em&gt;without&lt;/em&gt; transforming them explicitly. If you transform an array using &lt;code&gt;map()&lt;/code&gt; or &lt;a href="https://masteringjs.io/tutorials/fundamentals/filter"&gt;&lt;code&gt;filter()&lt;/code&gt;&lt;/a&gt; before sorting, you lose the original array.&lt;/p&gt;

&lt;p&gt;Sorting by date properties is a convenient one-liner because &lt;a href="https://masteringjs.io/tutorials/fundamentals/compare-dates"&gt;comparing dates in JavaScript&lt;/a&gt; is easy: subtracting 2 dates returns the difference between the two dates in milliseconds.&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;d1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2019-06-01&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;d2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2018-06-01&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;d3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2019-06-01&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;d1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="nx"&gt;d1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;d2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 31536000000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if you want to sort by a &lt;code&gt;createdAt&lt;/code&gt; property, all you need to do is subtract the values of &lt;code&gt;createdAt&lt;/code&gt; in the &lt;code&gt;sort()&lt;/code&gt; &lt;a href="https://masteringjs.io/tutorials/fundamentals/callbacks"&gt;callback&lt;/a&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;d1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2019-06-01&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;d2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2018-06-01&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;d3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2019-06-01&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;objects&lt;/span&gt; &lt;span class="o"&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;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Test 1&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;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;d2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Test 2&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;createdAt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Test 3&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="nx"&gt;objects&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;createdAt&lt;/span&gt; &lt;span class="o"&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;createdAt&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// [ 'Test 2', 'Test 1', 'Test 3' ]&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;objects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;o&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;o&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;h2&gt;
  
  
  2) Using String Conversions
&lt;/h2&gt;

&lt;p&gt;This trick is a bit less useful, but still interesting. Remember that &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort"&gt;JavaScript converts the array elements to strings before sorting&lt;/a&gt; &lt;em&gt;unless&lt;/em&gt; you pass a function parameter to &lt;code&gt;sort()&lt;/code&gt;. That means you can define a custom &lt;a href="https://masteringjs.io/tutorials/fundamentals/tostring"&gt;&lt;code&gt;toString()&lt;/code&gt; function&lt;/a&gt; and JavaScript will sort objects by that &lt;code&gt;toString()&lt;/code&gt; function as shown below.&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;class&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&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="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&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;length&lt;/span&gt;&lt;span class="p"&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;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;333&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;4444&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;22&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="c1"&gt;// Sorts users by `name.length`!&lt;/span&gt;
&lt;span class="c1"&gt;// [ Test { name: '22' }, Test { name: '333' }, Test { name: '4444' } ]&lt;/span&gt;
&lt;span class="nx"&gt;arr&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach is limited because you can only define one &lt;code&gt;toString()&lt;/code&gt; function for a given class. And, if you want to change the sort order, you need to change each object's &lt;code&gt;toString()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;But this approach can be very useful if your object's &lt;code&gt;toString()&lt;/code&gt; function is exactly what you want to sort by.&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;class&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&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;arr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John&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;Smith&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bill&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;Jones&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;User&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Mike&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;Palmer&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="c1"&gt;// Sort users by "last, first"&lt;/span&gt;
&lt;span class="nx"&gt;arr&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3) Sorting by Arbitrary Orderings
&lt;/h2&gt;

&lt;p&gt;Suppose you have an array of characters from &lt;em&gt;Star Trek: The Next Generation&lt;/em&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;characters&lt;/span&gt; &lt;span class="o"&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;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Jean-Luc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Picard&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Captain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;59&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Will&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Riker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Commander&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;29&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Geordi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;La Forge&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Lieutenant&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;29&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;Sorting by name or age is easy. But what about sorting by &lt;code&gt;rank&lt;/code&gt;? Turns out that's easy too. Create a map from ranks to numbers, and sort by the difference in ranks as shown below.&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;rankOrder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="p"&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;Captain&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&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;Commander&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&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;Lieutenant&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nx"&gt;characters&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="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;rankOrder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&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;rank&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;rankOrder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&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;rank&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Picard, Riker, La Forge&lt;/span&gt;
&lt;span class="nx"&gt;characters&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>javascript</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>3 Neat Features of JavaScript's Much-Maligned Date Class</title>
      <dc:creator>Mastering JS</dc:creator>
      <pubDate>Tue, 21 Sep 2021 22:23:37 +0000</pubDate>
      <link>https://forem.com/masteringjs/3-neat-features-of-javascript-s-much-maligned-date-class-273l</link>
      <guid>https://forem.com/masteringjs/3-neat-features-of-javascript-s-much-maligned-date-class-273l</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a7TSEZf7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ez74ymy9twxwwt134p6n.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a7TSEZf7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ez74ymy9twxwwt134p6n.jpeg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;JavaScript's &lt;code&gt;Date&lt;/code&gt; class is a common source of frustration, and there's countless blog posts on the internet describing precisely why &lt;code&gt;Date&lt;/code&gt; is so hard to work with:&lt;/p&gt;

&lt;p&gt;1) Formatting is limited and hard to work with, and doesn't have great browser support&lt;br&gt;
2) The string formats that the &lt;code&gt;Date()&lt;/code&gt; constructor accepts are quirky and hard to grasp&lt;br&gt;
3) Limited timezone support&lt;br&gt;
4) And many more&lt;/p&gt;

&lt;p&gt;The limitations of &lt;code&gt;Date&lt;/code&gt; are a big reason why developers are so excited about the new &lt;a href="https://tc39.es/proposal-temporal/docs/"&gt;Temporal API&lt;/a&gt;. But don't write off the &lt;code&gt;Date&lt;/code&gt; class completely. Believe it or not, the &lt;code&gt;Date&lt;/code&gt; class has a few delightful features that we love.&lt;/p&gt;
&lt;h3&gt;
  
  
  1) You can &lt;a href="https://masteringjs.io/tutorials/fundamentals/compare-dates"&gt;compare dates&lt;/a&gt; using &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;One tragic limitation of the &lt;code&gt;Date()&lt;/code&gt; class is that neither &lt;code&gt;===&lt;/code&gt; nor &lt;code&gt;==&lt;/code&gt; can determine whether two dates are equal.&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;d1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2019-06-01&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;d2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2018-06-01&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;d3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2019-06-01&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;d1&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nx"&gt;d1&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But, oddly enough, &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&lt;/code&gt; work for determining whether one date is before or after another. You don't need Moment's or date-fns' &lt;code&gt;isAfter()&lt;/code&gt; function.&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;d1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;d2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;
&lt;span class="nx"&gt;d1&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// false&lt;/span&gt;

&lt;span class="nx"&gt;d2&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2) Subtracting two dates returns the difference between the dates in milliseconds
&lt;/h3&gt;

&lt;p&gt;The addition operator &lt;code&gt;+&lt;/code&gt; notoriously doesn't work well with JavaScript dates. Adding &lt;code&gt;1000&lt;/code&gt; to a date just returns a string with &lt;code&gt;1000&lt;/code&gt; concatenated to the end of the date as a string.&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;d&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;d&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 'Tue Sep 21 2021 18:06:39 GMT-0400 (Eastern Daylight Time)1000'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, if you subtract two &lt;code&gt;Date&lt;/code&gt; instances, you get back the difference in milliseconds.&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;d1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2019-06-01&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;d2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2018-06-01&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;d3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2019-06-01&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;d1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;d3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 0&lt;/span&gt;
&lt;span class="nx"&gt;d1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;d2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 1 year in milliseconds, 1000 * 60 * 60 * 24 * 365&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even better, if subtract a number from a date, JavaScript converts the date to the &lt;a href="https://masteringjs.io/tutorials/fundamentals/timestamps"&gt;unix timestamp&lt;/a&gt; and subtracts the number from that. So, while you can't easily add to a date, you can subtract from a date.&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;d1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2019-06-01&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;d1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 2019-06-01T00:00:00.000Z&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d1&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2018-06-01T00:00:00.000Z&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, to add 1 year to a date (modulo leap years, leap seconds, etc.) you can subtract a negative number from the date as shown below.&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;d2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2018-06-01&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;d2&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;365&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 2019-06-01T00:00:00.000Z&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3) Basic Timezone Formatting
&lt;/h3&gt;

&lt;p&gt;Most developers don't know that you can format dates in arbitrary timezones using the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toLocaleString"&gt;&lt;code&gt;toLocaleString()&lt;/code&gt; method&lt;/a&gt;. The tradeoff is that some older browsers, like IE, don't support IANA timezone names. Here's an example of basic &lt;a href="https://masteringjs.io/tutorials/fundamentals/date_format"&gt;date formatting in JavaScript&lt;/a&gt; with timezones.&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;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2019-06-01T08:00:00.000Z&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// "June 01, 2019, 2 AM"&lt;/span&gt;
&lt;span class="nx"&gt;date&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toLocaleString&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-US&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;month&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;long&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;day&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2-digit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;year&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;numeric&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;hour&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2-digit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;timeZone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;America/Denver&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="c1"&gt;// 6 hours behind UTC&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While &lt;code&gt;toLocaleString()&lt;/code&gt; isn't perfect, it does provide some rudimentary formatting, including timezone support. We still recommend using &lt;a href="https://thecodebarbarian.com/formatting-javascript-dates-with-moment-js.html"&gt;Moment&lt;/a&gt; or &lt;a href="https://date-fns.org/"&gt;date-fns&lt;/a&gt; for most apps, but you can get away with &lt;code&gt;toLocaleString()&lt;/code&gt; for some basic formatting.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>3 TypeScript Tricks You Can Use in JavaScript</title>
      <dc:creator>Mastering JS</dc:creator>
      <pubDate>Fri, 03 Sep 2021 21:44:59 +0000</pubDate>
      <link>https://forem.com/masteringjs/3-typescript-tricks-you-can-use-in-javascript-1m75</link>
      <guid>https://forem.com/masteringjs/3-typescript-tricks-you-can-use-in-javascript-1m75</guid>
      <description>&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%2Fpi8vzugvaadx8g7a223w.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%2Fpi8vzugvaadx8g7a223w.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TypeScript is growing rapidly in popularity, but &lt;a href="https://www.getrevue.co/profile/masteringjs/issues/is-typescript-worth-it-307679" rel="noopener noreferrer"&gt;isn't worth the effort for some projects&lt;/a&gt;. However, even if you're writing JavaScript, there's some patterns you can learn from TypeScript. Here's 3 of our favorite TypeScript-inspired patterns for JavaScript.&lt;/p&gt;

&lt;h2&gt;
  
  
  1) &lt;a href="https://masteringjs.io/tutorials/fundamentals/enum" rel="noopener noreferrer"&gt;JavaScript Enums&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;TypeScript has support for enums, which are a neat pattern for defining an object whose keys you can use in place of hard-coded strings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kr"&gt;enum&lt;/span&gt; &lt;span class="nx"&gt;Direction&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;Up&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Down&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;Right&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;JavaScript doesn't support enums. But TypeScript compiles to JavaScript, so what does the above code turn into? Turns out TypeScript enums compile into &lt;a href="https://masteringjs.io/tutorials/fundamentals/pojo" rel="noopener noreferrer"&gt;JavaScript POJOs&lt;/a&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Direction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Up&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Up&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Down&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Down&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Left&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Right&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;You can also make &lt;code&gt;Direction&lt;/code&gt; immutable using &lt;code&gt;Object.freeze()&lt;/code&gt;, which makes &lt;code&gt;Direction&lt;/code&gt; pretty close to a TypeScript enum. And that means you can do what you expect to do with enums in other languages:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Get allowed enum values: &lt;code&gt;Object.keys(Direction)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Check if a value equals an enum value: &lt;code&gt;val === Direction.Up&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Check if a value is in the enum: &lt;code&gt;Object.hasOwnProperty(val)&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2) &lt;a href="http://thecodebarbarian.com/whats-new-in-mongoose-53-orfail-and-global-toobject.html" rel="noopener noreferrer"&gt;&lt;code&gt;orFail()&lt;/code&gt;&lt;/a&gt; helpers to avoid null checks
&lt;/h2&gt;

&lt;p&gt;TypeScript requires you to check for &lt;code&gt;null&lt;/code&gt; query results in Mongoose. This is good practice, but also gets a bit cumbersome if you need to do it over and over again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// TypeScript reports an error "Object is possibly 'null'."&lt;/span&gt;
&lt;span class="c1"&gt;// Need to add a `if (doc != null)` check&lt;/span&gt;
&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Mongoose queries have a neat &lt;code&gt;orFail()&lt;/code&gt; helper that throws an error if there's no result, which means you can go about using &lt;code&gt;doc&lt;/code&gt; &lt;strong&gt;without&lt;/strong&gt; explicitly checking for &lt;code&gt;null&lt;/code&gt;. This is because &lt;code&gt;orFail()&lt;/code&gt; marks the query as resolving to a &lt;a href="https://www.typescriptlang.org/docs/handbook/utility-types.html" rel="noopener noreferrer"&gt;NonNullable&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;doc&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;Model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;orFail&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Works!&lt;/span&gt;
&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use this &lt;code&gt;orFail()&lt;/code&gt; pattern a lot in our TypeScript tests, because it saves us from having to add repetitive &lt;code&gt;if&lt;/code&gt; checks. If the &lt;code&gt;orFail()&lt;/code&gt; is triggered, the error bubbles up to error handling.&lt;/p&gt;

&lt;p&gt;However, there's no reason why you can't use &lt;code&gt;orFail()&lt;/code&gt; in JavaScript! Just because TypeScript isn't there to tell you there's a problem, doesn't mean the problem isn't there.&lt;/p&gt;

&lt;p&gt;Similarly, if you have other functions that may return &lt;code&gt;null&lt;/code&gt; if a value is not found, consider wrapping them in a function that throws an error if the value is not found. It can save you a lot of &lt;code&gt;null&lt;/code&gt; checks!&lt;/p&gt;

&lt;h2&gt;
  
  
  3) Use &lt;a href="https://masteringjs.io/tutorials/fundamentals/map" rel="noopener noreferrer"&gt;JavaScript maps&lt;/a&gt; for objects with unknown types
&lt;/h2&gt;

&lt;p&gt;TypeScript makes it just a little easier to define a map with arbitrary keys than an object with arbitrary keys.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// An object with string keys and values of type `T`&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;AnyObject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;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;k&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Map with string keys and values of type `T`&lt;/span&gt;
&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;AnyMap&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;T&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;TypeScript makes working with maps to store arbitrary key/value mappings easier, and with good reason: maps support mapping from keys of arbitrary type.&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;fakeMap&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt;
&lt;span class="nx"&gt;fakeMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;fakeMap&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;fakeMap&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// { '1': string }&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;1&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;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Map(2) { 1 =&amp;gt; 'number', '1' =&amp;gt; 'string' }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The issue is that JavaScript object keys can only be strings or symbols, so JavaScript always converts object keys to strings. That's why you should use maps in cases where you aren't sure that the keys you're using are strings.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Using `then()` vs Async/Await in JavaScript</title>
      <dc:creator>Mastering JS</dc:creator>
      <pubDate>Wed, 25 Aug 2021 18:44:27 +0000</pubDate>
      <link>https://forem.com/masteringjs/using-then-vs-async-await-in-javascript-2pma</link>
      <guid>https://forem.com/masteringjs/using-then-vs-async-await-in-javascript-2pma</guid>
      <description>&lt;p&gt;When making async requests, you can either use &lt;a href="https://masteringjs.io/tutorials/fundamentals/then"&gt;&lt;code&gt;then()&lt;/code&gt;&lt;/a&gt; or &lt;a href="https://masteringjs.io/tutorials/fundamentals/async-await"&gt;async/await&lt;/a&gt;. Async/await and &lt;code&gt;then()&lt;/code&gt; are very similar.&lt;br&gt;
The difference is that in an &lt;a href="https://thecodebarbarian.com/async-functions-in-javascript.html"&gt;async function&lt;/a&gt;, JavaScript will pause the function execution until the promise settles. With &lt;code&gt;then()&lt;/code&gt;, the rest of the function will continue to execute but JavaScript won't execute the &lt;code&gt;.then()&lt;/code&gt; callback until the promise settles.&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;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;test&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ready&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;example&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://httpbin.org/get&lt;/span&gt;&lt;span class="dl"&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;I will print second&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="nx"&gt;test&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;I will print first&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;If you use promise chaining with &lt;code&gt;then()&lt;/code&gt;, you need to put any logic you want to execute after the request in the &lt;a href="https://masteringjs.io/tutorials/fundamentals/promise-chaining"&gt;promise chain&lt;/a&gt;. Any code that you put after &lt;code&gt;fetch()&lt;/code&gt; will execute immediately, &lt;strong&gt;before&lt;/strong&gt; the &lt;code&gt;fetch()&lt;/code&gt; is done.&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;function&lt;/span&gt; &lt;span class="nx"&gt;test&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Ready&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;example&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://httpbin.org/get&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is inside the then() 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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is after the fetch statement where we are now executing other code that is not async&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="nx"&gt;test&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="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;this is after the entire function&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;We recommend using async/await where possible, and minimize promise chaining. Async/await makes JavaScript code more accessible to developers that aren't as familiar with JavaScript, and much easier to read.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Mastering JS' 5 Best Promises Tutorials</title>
      <dc:creator>Mastering JS</dc:creator>
      <pubDate>Mon, 16 Aug 2021 16:50:22 +0000</pubDate>
      <link>https://forem.com/masteringjs/mastering-js-5-best-promises-tutorials-4dbc</link>
      <guid>https://forem.com/masteringjs/mastering-js-5-best-promises-tutorials-4dbc</guid>
      <description>&lt;p&gt;&lt;a href="http://masteringjs.io/tutorials/fundamentals/promise"&gt;Promises&lt;/a&gt; are one of the most important concepts in &lt;a href="https://masteringjs.io/"&gt;JavaScript&lt;/a&gt;. It is nearly impossible to write a modern JavaScript app without a &lt;a href="https://masteringjs.io/tutorials/fundamentals/then"&gt;&lt;code&gt;then()&lt;/code&gt; function&lt;/a&gt; popping up somewhere.&lt;/p&gt;

&lt;p&gt;Since promises are so fundamental to modern JavaScript, it pays to really understand how promises work in depth. With that in mind, here's some of our most popular tutorials on promises:&lt;/p&gt;

&lt;p&gt;1) &lt;a href="https://masteringjs.io/tutorials/fundamentals/then"&gt;The Promise then() Function in JavaScript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;then()&lt;/code&gt; function is the primary way you interact with promises. Here's how it works.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zJsLNbZz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vunh086r6zjgc23vvhhz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zJsLNbZz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vunh086r6zjgc23vvhhz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2) &lt;a href="https://masteringjs.io/tutorials/fundamentals/promise-chaining"&gt;JavaScript Promise Chaining&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;then()&lt;/code&gt; function is used for &lt;em&gt;chaining&lt;/em&gt; promises. This tutorial explains what it means to chain promises, and how you can chain promises like a pro.&lt;/p&gt;

&lt;p&gt;3) &lt;a href="https://masteringjs.io/tutorials/fundamentals/promise-create"&gt;JavaScript Create Promise&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;then()&lt;/code&gt; function helps you work with promises, but how do you &lt;a href="https://masteringjs.io/tutorials/fundamentals/promise-create"&gt;create a promise&lt;/a&gt; in the first place? This tutorial shows you how.&lt;/p&gt;

&lt;p&gt;4) &lt;a href="https://masteringjs.io/tutorials/fundamentals/catch"&gt;The Promise &lt;code&gt;catch()&lt;/code&gt; Function in JavaScript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;catch()&lt;/code&gt; function is a commonly used pattern for handling errors in promises. Did you know that &lt;code&gt;catch()&lt;/code&gt; is a one-line syntactic sugar on top of &lt;code&gt;then()&lt;/code&gt;? This tutorial explains how &lt;code&gt;catch()&lt;/code&gt; works.&lt;/p&gt;

&lt;p&gt;5) &lt;a href="https://masteringjs.io/tutorials/fundamentals/promise-all"&gt;The &lt;code&gt;Promise.all()&lt;/code&gt; Function in JavaScript&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Promise.all()&lt;/code&gt; function is how you execute multiple promises in parallel. It is especially useful for executing multiple &lt;a href="https://masteringjs.io/tutorials/fundamentals/async-await"&gt;async functions&lt;/a&gt; in parallel and waiting for all of them to finish. This tutorial explains how &lt;code&gt;Promise.all()&lt;/code&gt; works.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Mastering JS' 4 Best ESLint Tutorials</title>
      <dc:creator>Mastering JS</dc:creator>
      <pubDate>Thu, 12 Aug 2021 16:06:33 +0000</pubDate>
      <link>https://forem.com/masteringjs/mastering-js-4-best-eslint-tutorials-3b4d</link>
      <guid>https://forem.com/masteringjs/mastering-js-4-best-eslint-tutorials-3b4d</guid>
      <description>&lt;p&gt;At Mastering JS, we love &lt;a href="https://masteringjs.io/eslint"&gt;ESLint&lt;/a&gt;. However, ESLint is one of those tools that we strive to work with as &lt;strong&gt;little&lt;/strong&gt; as possible. Every minute you spent tinkering with your linter config is a minute that you're not spending working on features or fixes. So make sure it's worth the effort!&lt;/p&gt;

&lt;p&gt;Here's some of our most popular tutorials for ESLint:&lt;/p&gt;

&lt;p&gt;4) &lt;a href="https://masteringjs.io/tutorials/eslint/config"&gt;Intro to ESLint Config Files&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This tutorial shows how to get started with your own ESLint config, including what version of JavaScript you're using and what rules you want to enforce.&lt;/p&gt;

&lt;p&gt;3) &lt;a href="https://masteringjs.io/tutorials/eslint/rules"&gt;Understanding ESLint Rules&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once you know how to create an &lt;a href="https://masteringjs.io/tutorials/eslint/config"&gt;ESLint config file&lt;/a&gt;, you need to configure rules. Even if you're using a preset config, like &lt;a href="https://standardjs.com/"&gt;Standard&lt;/a&gt;, you may find yourself wanting to overwrite default rules that don't make sense for your application. This tutorial shows you how to configure ESLint rules, from basic enable/disable to sophisticated config options.&lt;/p&gt;

&lt;p&gt;2) &lt;a href="https://masteringjs.io/tutorials/eslint/fix"&gt;Using ESLint's --fix Flag&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;ESLint can fix violations of certain rules automatically. Here's how you can use &lt;code&gt;--fix&lt;/code&gt;, including how to set &lt;code&gt;--fix&lt;/code&gt; when using npm scripts.&lt;/p&gt;

&lt;p&gt;1) &lt;a href="https://masteringjs.io/tutorials/eslint/ignore"&gt;Ignore Lines and Files In ESLint&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Isn't it ironic that our most popular ESLint tutorial is how to disable ESLint? Well intentioned lint rules are helpful, but there's an exception to just about every rule. This tutorial shows you how to disable one ESLint rule for one line, one ESLint rule for one file, or ignore all rules in one file.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Mastering JS' 7 Best JavaScript Fundamentals Tutorials</title>
      <dc:creator>Mastering JS</dc:creator>
      <pubDate>Tue, 20 Jul 2021 14:44:09 +0000</pubDate>
      <link>https://forem.com/masteringjs/mastering-js-7-best-javascript-fundamentals-tutorials-27e7</link>
      <guid>https://forem.com/masteringjs/mastering-js-7-best-javascript-fundamentals-tutorials-27e7</guid>
      <description>&lt;p&gt;At &lt;a href="https://masteringjs.io/"&gt;Mastering JS&lt;/a&gt;, we think learning JavaScript fundamentals is much higher ROI than learning any particular framework. Two reasons why:&lt;/p&gt;

&lt;p&gt;1) Fundamentals rarely change. The JavaScript language spec doesn't allow backwards breaking changes. The &lt;a href="https://masteringjs.io/tutorials/fundamentals/void"&gt;void operator&lt;/a&gt; will work the same way in 5 years as it does today.&lt;br&gt;
2) Fundamentals are the same regardless of what framework you use. If you switch jobs tomorrow, you'll still be able to apply your fundamental language skills even if your new job does things differently.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--43ITDQVl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akudrh1pjt4lkgyc0dc5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--43ITDQVl--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/akudrh1pjt4lkgyc0dc5.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  7. &lt;a href="https://masteringjs.io/tutorials/fundamentals/then"&gt;The Promise then() Function in JavaScript&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://masteringjs.io/tutorials/fundamentals/promise"&gt;Promises&lt;/a&gt; and promise chaining, explained.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. &lt;a href="https://masteringjs.io/tutorials/fundamentals/array-splice"&gt;Understanding Array.splice() in JavaScript&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;splice()&lt;/code&gt; function lets you add and remove elements from the middle of an array. Here's how it works.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. &lt;a href="https://masteringjs.io/tutorials/fundamentals/compare-dates"&gt;Compare Dates in JavaScript&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Checking whether two dates are equal in JavaScript is tricky, this tutorial explains how. On the bright side, you can use &lt;code&gt;&amp;lt;&lt;/code&gt; and &lt;code&gt;&amp;gt;&lt;/code&gt; to compare whether one date is before or after another.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. &lt;a href="https://masteringjs.io/tutorials/fundamentals/pojo"&gt;What is a Plain Old JavaScript Object (POJO)?&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Whether an object is a POJO or not is a nuanced and commonly debated topic. This tutorial goes into detail about why checking whether a value is a POJO is tricky.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. &lt;a href="https://masteringjs.io/tutorials/fundamentals/foreach-object"&gt;Iterating Through an Object with &lt;code&gt;forEach()&lt;/code&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Some &lt;a href="https://masteringjs.io/eslint"&gt;ESLint&lt;/a&gt; presets require you to use &lt;code&gt;forEach()&lt;/code&gt; rather than conventional loops. That means you need to iterate through objects using &lt;code&gt;forEach()&lt;/code&gt;. This tutorial shows you how.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. [How to Use forEach() in JavaScript
&lt;/h3&gt;

&lt;p&gt;](&lt;a href="https://masteringjs.io/tutorials/fundamentals/foreach"&gt;https://masteringjs.io/tutorials/fundamentals/foreach&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;While we do not recommend using &lt;code&gt;forEach()&lt;/code&gt; to &lt;a href="https://masteringjs.io/tutorials/fundamentals/array-iterate"&gt;iterate arrays in JavaScript&lt;/a&gt;, &lt;code&gt;forEach()&lt;/code&gt; is an established part of JavaScript and worth mastering. This tutorial tells you what you need to know about &lt;code&gt;forEach()&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;a href="https://masteringjs.io/tutorials/fundamentals/string-concat"&gt;3 Ways to Concatenate Strings in JavaScript&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Concatenating two strings is one of the most fundamental tasks in JavaScript. This tutorial explains the tradeoffs of 3 different ways to concatenate strings.&lt;/p&gt;

</description>
      <category>javascript</category>
    </item>
    <item>
      <title>Mastering JS' 5 Best Vue Tutorials</title>
      <dc:creator>Mastering JS</dc:creator>
      <pubDate>Wed, 14 Jul 2021 15:16:59 +0000</pubDate>
      <link>https://forem.com/masteringjs/mastering-js-5-best-vue-tutorials-2edl</link>
      <guid>https://forem.com/masteringjs/mastering-js-5-best-vue-tutorials-2edl</guid>
      <description>&lt;p&gt;We love &lt;a href="https://masteringjs.io/vue"&gt;Vue&lt;/a&gt; at Mastering JS. We even built our &lt;a href="https://masteringjs.io/jobs"&gt;JavaScript job board&lt;/a&gt; in Vue, and wrote about the best &lt;a href="https://masteringjs.io/tutorials/vue/books"&gt;Vue books&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here's our 5 most popular Vue.js tutorials.&lt;/p&gt;

&lt;p&gt;5) &lt;a href="https://masteringjs.io/tutorials/vue/refs"&gt;An Introduction To Vue $refs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vue refs are a way to get access to a raw DOM element in your component. They're especially useful if you need to use a library that requires DOM elements, like &lt;a href="https://thecodebarbarian.com/accepting-stripe-payments-with-node-js.html"&gt;Stripe elements&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;4) &lt;a href="https://masteringjs.io/tutorials/vue/error-handling"&gt;Vue Error Handling&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vue's &lt;code&gt;errorCaptured&lt;/code&gt; hook is an extremely powerful tool that lets you handle errors that happen in child components. You can handle any error that occurs from your root component, &lt;strong&gt;even errors in async methods!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;3) &lt;a href="https://masteringjs.io/tutorials/vue/vue-3"&gt;What's New in Vue 3&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vue 3 is the same old Vue that we know and love, with a few new delightful surprises. Here's an overview of what's new in Vue 3.&lt;/p&gt;

&lt;p&gt;2) &lt;a href="https://masteringjs.io/tutorials/vue/drag-and-drop"&gt;How to Drag and Drop File Upload with Vue&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Vue makes it easy to handle drag events using the &lt;code&gt;@drag&lt;/code&gt;, which makes drag and drop file uploads easy. Here's how.&lt;/p&gt;

&lt;p&gt;1) &lt;a href="https://masteringjs.io/tutorials/vue/emit"&gt;The $emit Function in Vue&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;$emit()&lt;/code&gt; function is how a child component can communicate directly with it's parent. This tutorial describes how &lt;code&gt;$emit()&lt;/code&gt; works.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
      <category>codenewbie</category>
    </item>
  </channel>
</rss>
