<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Fábio Englert Moutinho</title>
    <description>The latest articles on DEV Community by Fábio Englert Moutinho (@fabioemoutinho).</description>
    <link>https://dev.to/fabioemoutinho</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%2F683733%2F6b895d96-19d1-4934-9a54-d267f3426633.png</url>
      <title>DEV Community: Fábio Englert Moutinho</title>
      <link>https://dev.to/fabioemoutinho</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/fabioemoutinho"/>
    <language>en</language>
    <item>
      <title>Getting Started with RxJS: All You Need to Know About Observables</title>
      <dc:creator>Fábio Englert Moutinho</dc:creator>
      <pubDate>Wed, 16 Nov 2022 13:17:49 +0000</pubDate>
      <link>https://dev.to/bitovi/getting-started-with-rxjs-all-you-need-to-know-about-observables-4dk9</link>
      <guid>https://dev.to/bitovi/getting-started-with-rxjs-all-you-need-to-know-about-observables-4dk9</guid>
      <description>&lt;p&gt;&lt;a href="https://rxjs.dev/guide/overview"&gt;RxJS&lt;/a&gt; is a library that combines the Observer pattern—where Observables or Subjects notify Observers of state changes—with functional programming to handle data changes over time.&lt;/p&gt;

&lt;p&gt;When programming with RxJS, you are usually:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Creating Observables to subscribe later&lt;/li&gt;
&lt;li&gt;Creating new Observables by piping existing Observables&lt;/li&gt;
&lt;li&gt;Subscribing to Observables to get data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As &lt;a href="https://rxjs.dev/guide/overview"&gt;Observables are “the most basic building block of RxJS"&lt;/a&gt;, having a solid understanding of Observables is paramount to becoming proficient in RxJS.&lt;/p&gt;

&lt;p&gt;In this blog post, you’ll learn what an Observable is, the different types of Observables and how they are helpful.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an Observable?
&lt;/h2&gt;

&lt;p&gt;In essence, Observables represent data (or a state) that changes over time. Observables have two critical methods you should know about: &lt;a href="https://rxjs.dev/api/index/class/Observable#subscribe"&gt;subscribe&lt;/a&gt; and &lt;a href="https://rxjs.dev/api/index/class/Observable#pipe"&gt;pipe&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Observable.subscribe()
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;subscribe&lt;/code&gt; will start the execution of an Observable and provides a way to observe Observable emitted notifications by passing Observer handlers.&lt;/p&gt;

&lt;p&gt;The Observer argument of &lt;code&gt;subscribe&lt;/code&gt; allows you to react when the Observable emits a new value, errors, or completes through &lt;code&gt;next&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;, and &lt;code&gt;complete&lt;/code&gt; callbacks.&lt;/p&gt;

&lt;p&gt;Each subscription to an Observable will create a new execution of the Observable.&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;// emit sequential numbers every second and console.log that number&lt;/span&gt;
&lt;span class="nf"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&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="na"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;:&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="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// if you don't care about error or complete, you can pass only the next function:&lt;/span&gt;
&lt;span class="nf"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;value&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://stackblitz.com/edit/typescript-jdkctb?devToolsHeight=100&amp;amp;file=index.ts"&gt;Code Available on StackBlitz&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Observable.pipe()
&lt;/h3&gt;

&lt;p&gt;The sole reason the &lt;code&gt;pipe&lt;/code&gt; method exists is to improve readability.&lt;/p&gt;

&lt;p&gt;Without &lt;code&gt;pipe&lt;/code&gt;, composing Observable streams with operators would be a nightmare. &lt;a href="https://rxjs.dev/guide/operators"&gt;Operators&lt;/a&gt; are pure functions that take a source Observable and return a new Observable.&lt;/p&gt;

&lt;p&gt;Imagine writing the following code to compose an Observable Stream:&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="cm"&gt;/**
 * 1. interval - emit sequential numbers every second
 * 2. map - multiply emitted values by 2
 * 3. map - emit a string `Result: ${x}`
 * 4. tap - log every emitted value
 */&lt;/span&gt;
&lt;span class="nf"&gt;tap&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;value&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;))(&lt;/span&gt;
  &lt;span class="nf"&gt;map&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`Result: &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="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nf"&gt;map&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="kr"&gt;number&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;x&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nf"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)))&lt;/span&gt;
&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Albeit the code above is valid, the &lt;code&gt;pipe&lt;/code&gt; method is always preferred.&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;pipe&lt;/code&gt; method, the code becomes more readable:&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="cm"&gt;/**
 * 1. interval - emit sequential numbers every second
 * 2. map - multiply emitted values by 2
 * 3. map - emit a string `Result: ${x}`
 * 4. tap - log every emitted value
 */&lt;/span&gt;
&lt;span class="nf"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="nf"&gt;map&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="o"&gt;=&amp;gt;&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;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
     &lt;span class="nf"&gt;map&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;`Result: &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="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="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;value&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://stackblitz.com/edit/typescript-eqws53?devToolsHeight=100&amp;amp;file=index.ts"&gt;Code Available on StackBlitz&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Subject?
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://rxjs.dev/api/index/class/Subject"&gt;Subject&lt;/a&gt; class extends the Observable class to allow multicasting emissions to all Observers - in other words: each new subscription to a Subject will not create a new execution of the Subject.&lt;/p&gt;

&lt;p&gt;Subjects keep track of all their Observers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Subject.next(), Subject.error() and Subject.complete()
&lt;/h3&gt;

&lt;p&gt;A Subject's &lt;code&gt;next&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;, and &lt;code&gt;complete&lt;/code&gt; methods will call all of its &lt;a href="https://rxjs.dev/guide/observer"&gt;Observers&lt;/a&gt;' &lt;code&gt;next&lt;/code&gt;, &lt;code&gt;error&lt;/code&gt;, and &lt;code&gt;complete&lt;/code&gt; methods.&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;mySubject1&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;Subject&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;mySubject2&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;Subject&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;mySubject1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Subject 1 Next: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&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="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Subject 1 Error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&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="nx"&gt;mySubject1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A Value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;mySubject1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Something bad happened&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;mySubject2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Subject 2 Next: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&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="na"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;:&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Subject 2 Complete`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;mySubject2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://stackblitz.com/edit/typescript-fbsnht?devToolsHeight=100&amp;amp;file=index.ts"&gt;Code Available on StackBlitz&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Subject.asObservable()
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;asObservable&lt;/code&gt; method is useful when you want to hide the Subject’s methods when exposing it to consumers that should only use it as an Observable.&lt;/p&gt;

&lt;p&gt;For example, you might expose the Subject in a service as an Observable, so components using that service will not be able to call the next method.&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;// MyService file&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mySubject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Subject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyType&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;public&lt;/span&gt; &lt;span class="nf"&gt;getSubject&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;MyType&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mySubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;asObservable&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// MyComponent file&lt;/span&gt;
&lt;span class="nx"&gt;myService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSubject&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// Property 'next' does not exist on type 'Observable&amp;lt;MyType&amp;gt;'.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What is a BehaviorSubject?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;constructor(value: T)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rxjs.dev/api/index/class/BehaviorSubject"&gt;BehaviorSubject&lt;/a&gt; extends Subject to ensure late subscribers are notified with the latest emitted value.&lt;/p&gt;

&lt;p&gt;A BehaviorSubject differs from a Subject in two ways.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;BehaviorSubject requires an initial value passed in its constructor&lt;/li&gt;
&lt;li&gt;Observers will receive the latest emitted value when they subscribe to a BehaviorSubject
&lt;/li&gt;
&lt;/ol&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;myBehaviorSubject&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;BehaviorSubject&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Initial Value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;myBehaviorSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;value&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`First Subscription: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&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="nx"&gt;myBehaviorSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Second Value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// a late subscription will receive the latest emitted value&lt;/span&gt;
&lt;span class="nx"&gt;myBehaviorSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;value&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Late Subscription: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://stackblitz.com/edit/typescript-zsa4xm?devToolsHeight=100&amp;amp;file=index.ts"&gt;Code Available on StackBlitz&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a ReplaySubject?
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;constructor(_bufferSize: number = Infinity, _windowTime: number = Infinity, _timestampProvider: TimestampProvider = dateTimestampProvider)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://rxjs.dev/api/index/class/ReplaySubject"&gt;ReplaySubject&lt;/a&gt; also extends Subject. ReplaySubject behaves similarly to BehaviorSubject but is capable of emitting multiple values when subscribed to.&lt;/p&gt;

&lt;p&gt;ReplaySubject differs from BehaviorSubject in three ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A ReplaySubject does not have an initial value.&lt;/li&gt;
&lt;li&gt;A ReplaySubject emits the last &lt;code&gt;bufferSize&lt;/code&gt; emissions when Observers subscribe to it. Values are held in a buffer for &lt;code&gt;windowTime&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;A ReplaySubject still replays values for Observers even if it has been completed with an error.
&lt;/li&gt;
&lt;/ol&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;myReplaySubject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;ReplaySubject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&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;myReplaySubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`ReplaySubject Next: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&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="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`ReplaySubject Error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&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="na"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;:&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`ReplaySubject Complete`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;myReplaySubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="nx"&gt;myReplaySubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="nx"&gt;myReplaySubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&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="nx"&gt;myReplaySubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Something bad happened&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// late subscription&lt;/span&gt;
&lt;span class="nx"&gt;myReplaySubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`ReplaySubject Next: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&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="na"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`ReplaySubject Error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&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="na"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;:&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`ReplaySubject Complete`&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;&lt;a href="https://stackblitz.com/edit/typescript-squcej?devToolsHeight=100&amp;amp;file=index.ts"&gt;Code Available on StackBlitz&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is an AsyncSubject?
&lt;/h2&gt;

&lt;p&gt;An &lt;a href="https://rxjs.dev/api/index/class/AsyncSubject"&gt;AsyncSubject&lt;/a&gt; only emits the last value to its Observers when it completes. That’s it.&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;myAsyncSubject&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;AsyncSubject&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nx"&gt;myAsyncSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;next&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`AsyncSubject Next: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&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="na"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;:&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`AsyncSubject Complete`&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;myAsyncSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;First Value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;myAsyncSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Second Value&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;setTimeout&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;myAsyncSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;complete&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://stackblitz.com/edit/typescript-pmcdtd?devToolsHeight=100&amp;amp;file=index.ts"&gt;Code Available on StackBlitz&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  On The Road to Mastering RxJS
&lt;/h2&gt;

&lt;p&gt;Now that you know how to use all the Observable Types—Observable, Subject, BehaviorSubject, ReplaySubject, and AsyncSubject—we highly recommend taking a look at the &lt;a href="https://rxjs.dev/guide/operators#categories-of-operators"&gt;operators' list in the official RxJS documentation&lt;/a&gt;, so you are at least exposed to most operators and know there’s a solution to every problem you are ever going to face.&lt;/p&gt;

&lt;p&gt;Finally, Bitovi offers a &lt;a href="https://www.bitovi.com/academy/learn-rxjs.html?hsLang=en-us"&gt;free RxJS course&lt;/a&gt; with great introductory and advanced content. You don't want to miss it. 👀&lt;/p&gt;

&lt;h3&gt;
  
  
  Are Subjects a tricky subject for you?
&lt;/h3&gt;

&lt;p&gt;Bitovi has expert &lt;a href="https://www.bitovi.com/frontend-javascript-consulting/angular-consulting"&gt;Angular consultants&lt;/a&gt; ready to help you tackle your most challenging RxJS questions. Schedule your free consultation today!&lt;/p&gt;

</description>
      <category>rxjs</category>
      <category>beginners</category>
      <category>angular</category>
    </item>
    <item>
      <title>Improve App Performance with the NgOptimizedImage Directive</title>
      <dc:creator>Fábio Englert Moutinho</dc:creator>
      <pubDate>Tue, 06 Sep 2022 21:27:04 +0000</pubDate>
      <link>https://dev.to/bitovi/improve-app-performance-with-the-ngoptimizedimage-directive-2mo</link>
      <guid>https://dev.to/bitovi/improve-app-performance-with-the-ngoptimizedimage-directive-2mo</guid>
      <description>&lt;p&gt;Newly released Angular 14.2 comes with a nifty image optimization feature that can be used to improve the performance of your application.&lt;/p&gt;

&lt;p&gt;In this blog post, we will take a look at the exciting new &lt;code&gt;NgOptimizedImage&lt;/code&gt; directive and explain how we used it to make this &lt;a href="https://e-commerce-scully-example.vercel.app/"&gt;example e-commerce application&lt;/a&gt; perform up to 50% better on Lighthouse scores!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fje7ouvy70kwsz1lupbqz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fje7ouvy70kwsz1lupbqz.png" alt="image showing improved lighthouse score of Angular e-commerce app after implementing NgOptimizedImage" width="693" height="286"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is NgOptimizedImage?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://angular.io/api/common/NgOptimizedImage"&gt;NgOptimizedImage&lt;/a&gt; is a Directive focused on improving Image Loading performance. As a happy side-effect, &lt;code&gt;NgOptimizedImage&lt;/code&gt; enforces best practices and improves Core Web Vitals scores, which might help your application rank higher on search engines.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important Note:&lt;/strong&gt; &lt;code&gt;NgOptimizedImage&lt;/code&gt; is on &lt;a href="https://angular.io/guide/releases#developer-preview"&gt;Developer Preview&lt;/a&gt;. Features on Developer Preview might change APIs without notice. If you decide to use &lt;code&gt;NgOptimizedImage&lt;/code&gt; on production, be aware when updating your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to Use NgOptimizedImage
&lt;/h2&gt;

&lt;p&gt;In order to use the &lt;code&gt;NgOptimizedImage&lt;/code&gt; directive, identifiable by the selector &lt;code&gt;img[rawSrc]&lt;/code&gt;, you need to import &lt;code&gt;NgOptimizedImage&lt;/code&gt; into your Module or Standalone Component.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NgOptimizedImage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common&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;h3&gt;
  
  
  Set Up an Image Loader
&lt;/h3&gt;

&lt;p&gt;Image Loaders are tools that host images and provide optimization services such as image resizing or compression.&lt;/p&gt;

&lt;p&gt;Angular now provides popular Image Loader configurations out of the box. In our e-commerce application example, we set up &lt;a href="https://imagekit.io/"&gt;ImageKit&lt;/a&gt; with the &lt;code&gt;provideImageKitLoader&lt;/code&gt; function, whose &lt;code&gt;path&lt;/code&gt; argument is the &lt;a href="https://imagekit.io/dashboard/url-endpoints"&gt;default URL endpoint&lt;/a&gt; for an account.&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;// src/app/app.module.ts&lt;/span&gt;

&lt;span class="c1"&gt;// ... other imports&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NgOptimizedImage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;provideImageKitLoader&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/common&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="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;declarations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HomeComponent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;CartComponent&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;BrowserModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;AppRoutingModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;ScullyLibModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;NgOptimizedImage&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;provideImageKitLoader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://ik.imagekit.io/fabioemoutinho&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
  &lt;span class="na"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppComponent&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Understand NgOptimizedImage Properties
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;NgOptimizedImage&lt;/code&gt; adds additional properties to an &lt;code&gt;img&lt;/code&gt; tag:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;rawSrc: string&lt;/code&gt;: instead of &lt;code&gt;src&lt;/code&gt; full URL, &lt;code&gt;rawSrc&lt;/code&gt; represents the source image name&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;code&gt;rawSrcset: string&lt;/code&gt;: a comma-separated &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-srcset"&gt;list of width or pixel density descriptors&lt;/a&gt;. Not required, but recommended. Usually used in conjunction with sizes attribute if you want to provide different image sources for different viewport sizes.&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- example taken from https://angular.io/api/common/NgOptimizedImage#properties --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;rawSrc=&lt;/span&gt;&lt;span class="s"&gt;"hello.jpg"&lt;/span&gt; &lt;span class="na"&gt;rawSrcset=&lt;/span&gt;&lt;span class="s"&gt;"100w, 200w"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;&amp;lt;!-- img tag above would output an img tag similar to the img below --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"path/hello.jpg"&lt;/span&gt; &lt;span class="na"&gt;srcset=&lt;/span&gt;&lt;span class="s"&gt;"path/hello.jpg?w=100 100w, path/hello.jpg?w=200 200w"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;priority: boolean&lt;/code&gt;: defaults to false; If true, adds &lt;a href="https://developer.chrome.com/blog/angular-image-directive/#mvp-for-the-ngoptimizedimage-directive"&gt;multiple optimizations&lt;/a&gt; to the image&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Images are going to be lazy-loaded by default. That is, it is going to be &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading"&gt;up to the browser to decide when to load the images&lt;/a&gt;. While lazy-loading an image is usually a good approach, &lt;a href="https://web.dev/priority-hints/#increase-the-priority-of-the-lcp-image"&gt;in some cases&lt;/a&gt;, like when you want to make sure the browser will download critical images first, you might want to set the &lt;code&gt;priority&lt;/code&gt; property to &lt;code&gt;true&lt;/code&gt; in order to increase the performance of your app.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;NgOptimizedImage&lt;/code&gt; directive also expects every image to have explicit &lt;code&gt;height&lt;/code&gt; and &lt;code&gt;width&lt;/code&gt; attributes.&lt;/p&gt;

&lt;p&gt;Here are the changes we had to make on a component’s template to use the &lt;code&gt;NgOptimizedImage&lt;/code&gt; directive.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;  &amp;lt;!-- src/app/home/home.component.html ‐‐&amp;gt;
&lt;span class="err"&gt;
&lt;/span&gt;  &amp;lt;picture class="picture block relative overflow-hidden"&amp;gt;
    &amp;lt;img
&lt;span class="gd"&gt;-     [src]="product.image"
&lt;/span&gt;&lt;span class="gi"&gt;+     [rawSrc]="product.id + '.jpg'"
&lt;/span&gt;      [alt]="product.title"
      class="img not-loaded object-contain w-full h-full absolute top-0 left-0"
      (load)="onLoadImage($event)"
      (error)="onErrorImage($event)"
&lt;span class="gi"&gt;+     width="200"
+     height="200"
&lt;/span&gt;    /&amp;gt;
  &amp;lt;/picture&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Performance Results
&lt;/h2&gt;

&lt;p&gt;In our example application, we removed &lt;code&gt;scully&lt;/code&gt; to better measure the impact of a vanilla implementation of the &lt;code&gt;NgOptimizedImage&lt;/code&gt; directive on the application’s home page. We tested two different scenarios:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://e-commerce-no-scully-example-angular-13.vercel.app/"&gt;https://e-commerce-no-scully-example-angular-13.vercel.app/&lt;/a&gt; - Angular 13.3.11&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://e-commerce-no-scully-example.vercel.app/"&gt;https://e-commerce-no-scully-example.vercel.app/&lt;/a&gt; - Angular 14.2.0, using &lt;code&gt;NgOptimizedImage&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We then ran Lighthouse locally (desktop) and had the following results:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Angular 13.3.11&lt;/th&gt;
&lt;th&gt;Angular 14.2 with NgOptimizedImage&lt;/th&gt;
&lt;th&gt;Impact&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;First Contentful Paint&lt;/td&gt;
&lt;td&gt;0.4 s&lt;/td&gt;
&lt;td&gt;0.3 s&lt;/td&gt;
&lt;td&gt;25% decrease&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Speed Index&lt;/td&gt;
&lt;td&gt;1.2 s&lt;/td&gt;
&lt;td&gt;0.6 s&lt;/td&gt;
&lt;td&gt;50% decrease&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Largest Contentful Paint&lt;/td&gt;
&lt;td&gt;1.7 s&lt;/td&gt;
&lt;td&gt;1.0 s&lt;/td&gt;
&lt;td&gt;41% decrease&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Time to Interactive&lt;/td&gt;
&lt;td&gt;0.5 s&lt;/td&gt;
&lt;td&gt;0.4 s&lt;/td&gt;
&lt;td&gt;20% decrease&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Total Blocking Time&lt;/td&gt;
&lt;td&gt;0 ms&lt;/td&gt;
&lt;td&gt;0 ms&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cumulative Layout Shift&lt;/td&gt;
&lt;td&gt;0.003&lt;/td&gt;
&lt;td&gt;0.003&lt;/td&gt;
&lt;td&gt;-&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Performance&lt;/td&gt;
&lt;td&gt;93&lt;/td&gt;
&lt;td&gt;99&lt;/td&gt;
&lt;td&gt;6.45% increase&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Even though you get excellent performance results with the automatic lazy loading of images, &lt;code&gt;NgOptimizedImage&lt;/code&gt; shines even brighter when combining the usage of image loaders with the &lt;code&gt;rawSrcset&lt;/code&gt; property and &lt;code&gt;sizes&lt;/code&gt; attribute. Implementing the &lt;code&gt;rawSrcset&lt;/code&gt; property and &lt;code&gt;sizes&lt;/code&gt; attribute enables you to further optimize your application for different devices, especially for mobile devices.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s Next for Angular’s Image Directive?
&lt;/h2&gt;

&lt;p&gt;Chrome’s blog post announcement about &lt;code&gt;NgOptimizedImage&lt;/code&gt; directive presents an interesting &lt;a href="https://developer.chrome.com/blog/angular-image-directive/#future-roadmap"&gt;roadmap&lt;/a&gt;, and we can expect many improvements like automatic &lt;code&gt;srcset&lt;/code&gt; and &lt;code&gt;sizes&lt;/code&gt; attributes for responsive images, automatic &lt;code&gt;height&lt;/code&gt; and &lt;code&gt;width&lt;/code&gt; attributes and more.&lt;/p&gt;

&lt;p&gt;Angular v14.2 introduces other interesting features that we will talk about next, stay tuned on &lt;a href="https://twitter.com/bitovi"&gt;Bitovi's Twitter&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Need help staying up to date with the latest version of Angular to take advantage of these cool new features? &lt;a href="https://www.bitovi.com/frontend-javascript-consulting/angular-consulting"&gt;Contact us&lt;/a&gt; for Angular Consulting help!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>performance</category>
      <category>seo</category>
    </item>
    <item>
      <title>Bitovi ESLint Config: Handpicked Rules to Improve Your Code</title>
      <dc:creator>Fábio Englert Moutinho</dc:creator>
      <pubDate>Mon, 08 Aug 2022 16:00:00 +0000</pubDate>
      <link>https://dev.to/bitovi/bitovi-eslint-config-handpicked-rules-to-improve-your-code-3p83</link>
      <guid>https://dev.to/bitovi/bitovi-eslint-config-handpicked-rules-to-improve-your-code-3p83</guid>
      <description>&lt;p&gt;Linting is an important step to ensure code quality, and it fits well as an automated process in the development pipeline. Most teams use the default lint configuration provided by their framework, missing opportunities to prevent runtime errors and increase code quality with the extended set of ESLint rules.&lt;/p&gt;

&lt;p&gt;Bitovi is happy to announce the &lt;a href="https://github.com/bitovi/eslint-config"&gt;@bitovi/eslint-config&lt;/a&gt; and &lt;a href="https://github.com/bitovi/eslint-plugin"&gt;@bitovi/eslint-plugin&lt;/a&gt; packages!&lt;/p&gt;

&lt;p&gt;In pursuit of greater code quality and better standards for Bitovi's clients and the Community, we carefully handpicked the best ESLint rules and created some of our own to fill existing gaps. We built &lt;code&gt;@bitovi/eslint-config&lt;/code&gt; upon existing recommended rule sets and selected rules to avoid common pitfalls based on experience with clients and internal projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  What’s in Bitovi ESLint Config?
&lt;/h2&gt;

&lt;p&gt;Our ESLint-config package has dedicated Angular and React rule sets, but your project can also benefit from other specific rule sets like RxJS. Here are a few of the Angular set rules included in our ESLint config:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Keep code clean by removing unused variables - &lt;code&gt;@typescript-eslint/no-unused-vars&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Avoid accessibility issues with keyboard navigation - &lt;code&gt;@angular-eslint/template/no-positive-tabindex&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Ensure elements with click event bindings are accessible - &lt;code&gt;@angular-eslint/template/click-events-have-key-events&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Ensure component classes with click event bindings are accessible - &lt;code&gt;@bitovi/host-listener-click-events-have-key-events&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start harnessing the full extent of Bitovi’s recommended ESLint rules by following two short steps.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Installation
&lt;/h2&gt;

&lt;p&gt;Install the ESLint-config package to get started! Run &lt;code&gt;npm i -D @bitovi/eslint-config&lt;/code&gt;, which is short for &lt;code&gt;npm install --save-dev @bitovi/eslint-config&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Usage
&lt;/h2&gt;

&lt;p&gt;Once installation is done, you can add any of the &lt;a href="https://github.com/bitovi/eslint-config#available-rules"&gt;rules provided by @bitovi/eslint-config&lt;/a&gt; to your project's ESLint config file extends array.&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;extends&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;@bitovi/eslint-config/angular&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;// or, if you only want a specific rule set like RxJS&lt;/span&gt;
  &lt;span class="kd"&gt;extends&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;@bitovi/eslint-config/rules/rxjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What’s next?
&lt;/h2&gt;

&lt;p&gt;We plan to add more custom ESLint rules to &lt;a href="https://github.com/bitovi/eslint-plugin"&gt;@bitovi/eslint-plugin&lt;/a&gt; package to help your project be more accessible, have a better SEO and Lighthouse Scores, and more!&lt;/p&gt;

&lt;p&gt;Interested in learning more? Take a look at our &lt;a href="https://github.com/bitovi/eslint-config/wiki/Roadmap"&gt;Roadmap&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Do you have ideas or suggestions? We’d love to hear about them. You can &lt;a href="https://github.com/bitovi/eslint-config/issues"&gt;open an issue at @bitovi/eslint-config repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have any questions, let us know in our &lt;a href="https://www.bitovi.com/community/slack"&gt;Community Slack&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>angular</category>
      <category>react</category>
      <category>eslint</category>
    </item>
    <item>
      <title>Always Know When to Use Share vs. ShareReplay</title>
      <dc:creator>Fábio Englert Moutinho</dc:creator>
      <pubDate>Mon, 25 Jul 2022 15:17:10 +0000</pubDate>
      <link>https://dev.to/bitovi/always-know-when-to-use-share-vs-sharereplay-2jdf</link>
      <guid>https://dev.to/bitovi/always-know-when-to-use-share-vs-sharereplay-2jdf</guid>
      <description>&lt;p&gt;Using &lt;code&gt;share&lt;/code&gt; and &lt;code&gt;shareReplay&lt;/code&gt; is pretty darn confusing. The way &lt;code&gt;share&lt;/code&gt; and &lt;code&gt;shareReplay&lt;/code&gt; work is not always obvious and might lead to unexpected behavior in your application.&lt;/p&gt;

&lt;p&gt;Fortunately, you have found this article and after reading you’ll understand the differences between &lt;code&gt;share&lt;/code&gt; and &lt;code&gt;shareReplay&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  share
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;share&lt;/code&gt; operator will &lt;a href="https://en.wikipedia.org/wiki/Multicast"&gt;multicast&lt;/a&gt; values emitted by a source Observable for subscribers.&lt;/p&gt;

&lt;p&gt;Multicast means data is sent to multiple destinations.&lt;/p&gt;

&lt;p&gt;As such, &lt;code&gt;share&lt;/code&gt; allows you to avoid multiple executions of the source Observable when there are multiple subscriptions. &lt;code&gt;share&lt;/code&gt; is particularly useful if you need to prevent repeated API calls or costly operations executed by Observables.&lt;/p&gt;

&lt;p&gt;The slightly modified code from the &lt;a href="https://rxjs.dev/api/operators/share"&gt;official documentation&lt;/a&gt; below has a shared source Observable that emits random numbers at 1-second intervals, up to two emissions. You can also run the example on &lt;a href="https://stackblitz.com/edit/mpkssl?devToolsHeight=100&amp;amp;file=index.ts"&gt;StackBlitz&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tap&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;take&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;share&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&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;source$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;interval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;tap&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Processing: &lt;/span&gt;&lt;span class="dl"&gt;'&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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="nf"&gt;take&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;// if you remove share, you will see that&lt;/span&gt;
  &lt;span class="c1"&gt;// each subscription will have its own execution of the source observable&lt;/span&gt;
  &lt;span class="nf"&gt;share&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;source$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subscription 1: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;source$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subscription 2: &lt;/span&gt;&lt;span class="dl"&gt;'&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="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="c1"&gt;// this subscription arrives late to the party. What will happen?&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;source$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subscription 3: &lt;/span&gt;&lt;span class="dl"&gt;'&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="mi"&gt;1500&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="cm"&gt;/* Example Run
### share operator logs:
--- 1 second
Processing: 0
subscription 1: 33
subscription 2: 33
--- 2 seconds
Processing: 1
subscription 1: 12
subscription 2: 12
subscription 3: 12

### without share operator logs:
--- 1 second
Processing: 0
subscription 1: 55
Processing: 0
subscription 2: 65
--- 2 seconds
Processing: 1
subscription 1: 64
Processing: 1
subscription 2: 2
--- 2.5 seconds
Processing: 0
subscription 3: 42
--- 3.5 seconds
Processing: 1
subscription 3: 95
*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  share 's Inner Observable: Subject
&lt;/h3&gt;

&lt;p&gt;When you subscribe to a shared Observable, you are &lt;a href="https://github.com/ReactiveX/rxjs/blob/7.5.5/src/internal/operators/share.ts#L192"&gt;actually subscribing to a Subject&lt;/a&gt; exposed by the &lt;code&gt;share&lt;/code&gt; operator. The &lt;code&gt;share&lt;/code&gt; operator &lt;a href="https://github.com/ReactiveX/rxjs/blob/7.5.5/src/internal/operators/share.ts#L235"&gt;also manages an inner Subscription to the source Observable&lt;/a&gt;. The inner &lt;code&gt;Subject&lt;/code&gt; is the reason multiple subscribers receive the same shared value, as they are receiving values from the &lt;code&gt;Subject&lt;/code&gt; exposed by the &lt;code&gt;share&lt;/code&gt; operator. See &lt;a href="https://stackblitz.com/edit/mpkssl?devToolsHeight=100&amp;amp;file=index.ts"&gt;previous example on StackBlitz&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  share's RefCount
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;share&lt;/code&gt; keeps a count of subscribers. Once the subscriber count reaches &lt;code&gt;0&lt;/code&gt;, &lt;code&gt;share&lt;/code&gt; will unsubscribe from the source Observable and reset its inner Observable (the &lt;code&gt;Subject&lt;/code&gt;). The following (late) subscriber will trigger a new Subscription to the source Observable, or in other words, a new execution of the source Observable. Here’s an example of this behavior, &lt;a href="https://stackblitz.com/edit/uwwa2f?devToolsHeight=100&amp;amp;file=index.ts"&gt;also available on StackBlitz&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;delay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;share&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;shareReplay&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tap&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rxjs&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;source$&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;defer&lt;/span&gt;&lt;span class="p"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;round&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;random&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;))).&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nf"&gt;tap&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Processing: &lt;/span&gt;&lt;span class="dl"&gt;'&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="nf"&gt;delay&lt;/span&gt;&lt;span class="p"&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;// shareReplay({ bufferSize: 1, refCount: true }),&lt;/span&gt;
  &lt;span class="nf"&gt;share&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;source$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subscription 1: &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nx"&gt;source$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subscription 2: &lt;/span&gt;&lt;span class="dl"&gt;'&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="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&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;source$&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;subscribe&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="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;subscription 3: &lt;/span&gt;&lt;span class="dl"&gt;'&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="mi"&gt;3500&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  shareReplay
&lt;/h2&gt;

&lt;p&gt;In some cases what you really need is a &lt;code&gt;share&lt;/code&gt; that is able to behave as a &lt;a href="https://rxjs.dev/api/index/class/BehaviorSubject"&gt;BehaviorSubject&lt;/a&gt; would. For example: if a cold Observable has a &lt;code&gt;share&lt;/code&gt; operator, like the code example above, a late subscriber to it would never get the values emitted before the subscription because it subscribed after &lt;code&gt;share&lt;/code&gt; operator reached &lt;code&gt;refCount&lt;/code&gt; 0, which means the &lt;code&gt;share&lt;/code&gt; operator unsubscribed from the source Observable and reset its inner Subject. The late subscriber would thus subscribe to a new inner Subject, which runs a new execution of the source Observable, in this case that means a second API call: exactly the opposite of what you really needed.&lt;/p&gt;

&lt;p&gt;That's why &lt;code&gt;shareReplay&lt;/code&gt; exists: it both shares the source Observable and replays the last emissions for late subscribers.&lt;/p&gt;

&lt;p&gt;Also, it does not keep a count of subscribers by default, but you may use the refCount option with a &lt;code&gt;true&lt;/code&gt; value to enable that behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  shareReplay's Inner Observable: ReplaySubject
&lt;/h3&gt;

&lt;p&gt;In contrast to &lt;code&gt;share&lt;/code&gt;, &lt;code&gt;shareReplay&lt;/code&gt; exposes a &lt;code&gt;ReplaySubject&lt;/code&gt; to subscribers. &lt;code&gt;ReplaySubject(1)&lt;/code&gt; is very &lt;a href="https://rxjs.dev/api/index/class/ReplaySubject#differences-with-behaviorsubject"&gt;similar&lt;/a&gt; to a &lt;code&gt;BehaviorSubject&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  shareReplay's RefCount
&lt;/h3&gt;

&lt;p&gt;Since &lt;code&gt;shareReplay&lt;/code&gt; does not keep track of a subscriber count by default, it is not able to unsubscribe to the source Observable. Ever. Unless you use the &lt;code&gt;refCount&lt;/code&gt; option.&lt;/p&gt;

&lt;p&gt;In order to use &lt;code&gt;shareReplay&lt;/code&gt; while getting rid of memory leak issues you can use &lt;code&gt;bufferSize&lt;/code&gt; and &lt;code&gt;refCount&lt;/code&gt; options: &lt;code&gt;shareReplay({ bufferSize: 1, refCount: true })&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;shareReplay&lt;/code&gt; never resets its inner &lt;code&gt;ReplaySubject&lt;/code&gt; when &lt;code&gt;refCount&lt;/code&gt; reaches 0, but does unsubscribe from the source Observable. Late subscribers will not trigger a new execution of the source Observable and will receive up to &lt;code&gt;N (bufferSize)&lt;/code&gt; emissions. &lt;a href="https://stackblitz.com/edit/uwwa2f?devToolsHeight=100&amp;amp;file=index.ts"&gt;Play with the previous example on StackBlitz&lt;/a&gt; to see the difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use with Caution
&lt;/h2&gt;

&lt;p&gt;In Angular, there are some gotchas when using &lt;code&gt;share&lt;/code&gt; and &lt;code&gt;shareReplay&lt;/code&gt;. Observables subscribed in the template with the &lt;code&gt;async&lt;/code&gt; pipe might reach refCount &lt;code&gt;0&lt;/code&gt; if unsubscribed automatically by the &lt;code&gt;async&lt;/code&gt; pipe when inside a &lt;code&gt;*ngIf&lt;/code&gt;, which would cause a new execution of the source Observable.&lt;/p&gt;

&lt;p&gt;You might feel like the God of Time and Cache using &lt;code&gt;share&lt;/code&gt; and &lt;code&gt;shareReplay&lt;/code&gt;, but you should be aware that with great power comes great responsibility. If you want a partner to help you manage the high complexity of &lt;code&gt;share&lt;/code&gt;, &lt;code&gt;shareReplay&lt;/code&gt; and RxJS best practices, &lt;a href="mailto:contact@bitovi.com"&gt;contact us today&lt;/a&gt;. 🙂&lt;/p&gt;

</description>
      <category>rxjs</category>
      <category>angular</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to Improve Your Angular E-Commerce Application with Scully</title>
      <dc:creator>Fábio Englert Moutinho</dc:creator>
      <pubDate>Tue, 21 Jun 2022 19:29:00 +0000</pubDate>
      <link>https://dev.to/bitovi/how-to-improve-your-angular-e-commerce-application-with-scully-40fj</link>
      <guid>https://dev.to/bitovi/how-to-improve-your-angular-e-commerce-application-with-scully-40fj</guid>
      <description>&lt;p&gt;Scully is a “Static Site Generator for Angular apps” that enables Angular apps to pre-render pages with dynamic content to improve performance metrics like First Contentful Paint (FCP), Time to Interactive (TTI), and others which are used by Search Engines to rank your website.&lt;/p&gt;

&lt;p&gt;But is Scully the right tool for your Angular E-Commerce Application?&lt;/p&gt;

&lt;p&gt;Let’s find out if it suits your needs. &lt;em&gt;SPOILER ALERT: yes, it probably does.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How does Scully work?
&lt;/h2&gt;

&lt;p&gt;Scully provides an additional step after Angular’s &lt;code&gt;build&lt;/code&gt; step, which will identify your application’s routes to be rendered, then serve your application and launch a browser instance to navigate through selected routes. When the browser finishes rendering each route, Scully copies its rendered content and saves everything in HTML files inside &lt;code&gt;dist&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;If you want to know how Scully works behind the curtains in more detail, take a look at &lt;a href="https://scully.io/docs/concepts/process/"&gt;The Scully Process&lt;/a&gt; page in the official documentation.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does Scully Improve An E-Commerce Application?
&lt;/h2&gt;

&lt;p&gt;Search Engine Optimization (SEO) is a must for any website nowadays, especially for E-Commerce Apps.&lt;/p&gt;

&lt;p&gt;Scully will help your E-Commerce Application rank higher on search results by statically rendering each product page, making the application load faster for users and search engines alike. Performance metrics used by search engines will also improve as a result of Scully’s pre-rendering process.&lt;/p&gt;

&lt;p&gt;The performance improvements will also lead to lower bounce rates and higher conversion rates, as users will have a better experience while navigating.&lt;/p&gt;

&lt;p&gt;In other words, Scully essentially caches the application with statically served files, improving load time, and making processing your application easier on browsers and search engines, since there will be no javascript functions to run and no need to make external HTTP calls to fetch data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;To install Scully, run &lt;code&gt;ng add @scullyio/init&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Scully will then ask which route renderer you would like to use. As of 2022, we recommend picking &lt;code&gt;Puppeteer&lt;/code&gt;, since other options are currently in beta.&lt;/p&gt;

&lt;p&gt;Once installation is done, you’ll notice there’s a new Scully config file, &lt;code&gt;scully.[project].config.ts&lt;/code&gt;, and &lt;code&gt;app.module.ts&lt;/code&gt; now imports &lt;code&gt;ScullyLibModule&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To match the usability of &lt;code&gt;ng serve&lt;/code&gt;, when developing you’ll need to run two terminals with the following commands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;ng build --watch&lt;/code&gt; - whenever there’s a file change, it will trigger the build step&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;npx scully --scanRoutes --watch&lt;/code&gt; - whenever the build files generated by &lt;code&gt;ng build --watch&lt;/code&gt; change, it will trigger Scully's build step&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you need to run both the static and regular builds at the same time, you can use &lt;code&gt;npx scully serve&lt;/code&gt;, but you won’t have automatic updates when there are changes in builds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic Routes
&lt;/h2&gt;

&lt;p&gt;Scully provides a pre-build step where it can fetch information and decide which routes your application will render based on any logic you see fit.&lt;/p&gt;

&lt;p&gt;In order to do that, you need to go to the &lt;code&gt;./scully.[project].config.ts&lt;/code&gt; file and edit the &lt;code&gt;routes&lt;/code&gt; property inside the exported &lt;code&gt;config&lt;/code&gt; object.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;routes&lt;/code&gt; property is an object that can configure multiple routes, and each route can have different logic to decide which children routes will be rendered.&lt;/p&gt;

&lt;p&gt;In the example below, we have a &lt;code&gt;/product/:slug&lt;/code&gt; route, and Scully will fetch the &lt;code&gt;url&lt;/code&gt; and run the &lt;code&gt;resultsHandler&lt;/code&gt; function with the response data. &lt;code&gt;resultsHandler&lt;/code&gt; must return a list of objects with the property defined in the property &lt;code&gt;property&lt;/code&gt;, which in this example has the &lt;code&gt;slug&lt;/code&gt; value. More information at the &lt;a href="https://scully.io/docs/Reference/config/"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Scully will then find out which routes should be rendered by replacing &lt;code&gt;:slug&lt;/code&gt; in the route &lt;code&gt;/product/:slug&lt;/code&gt; with the &lt;code&gt;slug&lt;/code&gt; property value for each object in &lt;code&gt;resultsHandler&lt;/code&gt; returned array.&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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&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;ScullyConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;projectRoot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;projectName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PROJECT-NAME-HERE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;outDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dist/static&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;routes&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;/product/:slug&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;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;json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://PRODUCT-API-HERE/products&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;property&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slug&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;resultsHandler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="c1"&gt;// you can process anything here,&lt;/span&gt;
          &lt;span class="c1"&gt;// but you must return a list of objects&lt;/span&gt;
          &lt;span class="c1"&gt;// that have a 'slug' property, as defined above in line 8&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="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Making API Data Static
&lt;/h2&gt;

&lt;p&gt;Caching API calls will make your application faster and less reliant on servers availability. With &lt;code&gt;useScullyTransferState&lt;/code&gt; method you are able to cache the results of Observables. This means, however, that to update the data statically served by &lt;code&gt;useScullyTransferState&lt;/code&gt; you will need to trigger a new Scully build and deploy pipeline.&lt;/p&gt;

&lt;p&gt;The first argument of the &lt;code&gt;useScullyTransferState&lt;/code&gt; method is the index that will be used to get the data at runtime.&lt;/p&gt;

&lt;p&gt;The second argument expects an Observable, which means you are not limited to caching API calls, you can cache heavy operation Observables too.&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;// some service method&lt;/span&gt;
&lt;span class="nf"&gt;getCatalog&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Catalog&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;transferState&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;useScullyTransferState&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;catalog&lt;/span&gt;&lt;span class="dl"&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;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Catalog&lt;/span&gt;&lt;span class="o"&gt;&amp;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;https://CATALOG-URL&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Not All API Requests Should Be Cached
&lt;/h2&gt;

&lt;p&gt;Should you wrap every Observable with &lt;code&gt;useScullyTransferState&lt;/code&gt;? Definitely not. There might be cases where observables should only run at runtime and don’t need to be cached.&lt;/p&gt;

&lt;p&gt;Good examples include observables that rely on login state, like &lt;code&gt;cart&lt;/code&gt; or &lt;code&gt;user&lt;/code&gt; data, or when you need to hide or show specific parts of your application in the static generated version only.&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;// ./src/app/app.component.ts example&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;
    &amp;lt;nav&amp;gt;
      &amp;lt;app-menu&amp;gt;&amp;lt;/app-menu&amp;gt;
      &amp;lt;app-cart *ngIf="!isScullyRunning"&amp;gt;&amp;lt;/app-cart&amp;gt;
    &amp;lt;/nav&amp;gt;
    &amp;lt;router-outlet&amp;gt;&amp;lt;/router-outlet&amp;gt;
  &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="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="nx"&gt;isScullyRunning&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;isScullyRunning&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;h2&gt;
  
  
  Relying on Environment Files
&lt;/h2&gt;

&lt;p&gt;When writing plugins or dealing with the Scully config file, you may need to import &lt;code&gt;environment.prod.ts&lt;/code&gt; or some other file.&lt;/p&gt;

&lt;p&gt;By default, Scully only transpiles &lt;code&gt;.ts&lt;/code&gt; files inside the &lt;code&gt;./scully&lt;/code&gt; folder. Fortunately, it’s rather simple to tell Scully that more files need to be transpiled to JavaScript.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;./scully/tsconfig.json&lt;/code&gt; file, add an &lt;code&gt;include&lt;/code&gt; property with the patterns/files you need. The &lt;code&gt;./**/**&lt;/code&gt; pattern will match all files inside &lt;code&gt;./scully&lt;/code&gt; folder, which is the default behavior if an &lt;code&gt;include&lt;/code&gt; property is not defined. Then, you only need to add specific files that exist outside of &lt;code&gt;./scully&lt;/code&gt; folder.&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;// ./scully/tsconfig.json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;compileOnSave&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;compilerOptions&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;esModuleInterop&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;importHelpers&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;lib&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ES2019&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="s2"&gt;dom&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="s2"&gt;module&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="s2"&gt;commonjs&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="s2"&gt;moduleResolution&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="s2"&gt;node&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="s2"&gt;sourceMap&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;target&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="s2"&gt;es2018&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="s2"&gt;types&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node&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="s2"&gt;skipLibCheck&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;skipDefaultLibCheck&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;typeRoots&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;../node_modules/@types&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="s2"&gt;allowSyntheticDefaultImports&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;include&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./**/*&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="s2"&gt;../src/environments/environment.prod.ts&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="s2"&gt;exclude&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;./**/*spec.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating a Custom Plugin for Incremental Builds
&lt;/h2&gt;

&lt;p&gt;Rendering all the pages each time a single product changes is a waste of time and resources. It might not have a huge impact when you have a small set of products, but what if your E-Commerce application has thousands of product pages to render?&lt;/p&gt;

&lt;p&gt;Implementing incremental builds is an optimized solution where only changed content is re-rendered and deployed, saving you and your organization time and money in CI pipeline and deployments.&lt;/p&gt;

&lt;p&gt;Scully has a very powerful plugin system that enables you to control the pre-render process. There’s more information about Scully plugins in &lt;a href="https://scully.io/docs/concepts/plugins/"&gt;Plugin Concept&lt;/a&gt; and &lt;a href="https://scully.io/docs/Reference/plugins/overview/"&gt;Plugin Reference&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Below is an example of a plugin approach to render specific products by passing a list of IDs with the &lt;code&gt;scully&lt;/code&gt; command. Command example: &lt;code&gt;npx scully --productIds=1,2,3&lt;/code&gt;. This approach expects that the build and deploy pipeline are triggered by a system (like a CMS) with an awareness of what content has changed.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;./scully/plugins/plugin.ts&lt;/code&gt;, a &lt;code&gt;product&lt;/code&gt; plugin is registered as a &lt;code&gt;router&lt;/code&gt; plugin, then used in &lt;code&gt;./scully.[project].config.ts&lt;/code&gt; file to configure how the routes in &lt;code&gt;/product/:slug&lt;/code&gt; are handled.&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;// ./scully/plugins/plugin.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;HandledRoute&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;registerPlugin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;httpGetJson&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@scullyio/scully&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../src/app/product/product.model&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;environment&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../../src/environments/environment.prod&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;yargs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yargs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;hideBin&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;yargs/helpers&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;product&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;productRoutes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;route&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="nb"&gt;Promise&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;HandledRoute&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;&amp;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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;yarg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;yargs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hideBin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;argv&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;argv&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;yarg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;productIds&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;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;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;argv&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="c1"&gt;// if there are --productIds being passed in npx scully --productIds=1,2,3&lt;/span&gt;
  &lt;span class="c1"&gt;// then only generate static files for those products&lt;/span&gt;
  &lt;span class="c1"&gt;// else fetch all products from API and map the returned IDs.&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;productIds&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="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;productIds&lt;/span&gt;
    &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;argv&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;productIds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;,&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;httpGetJson&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;environment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/products`&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;Product&lt;/span&gt;&lt;span class="p"&gt;[]).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;product&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;product&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;span class="nf"&gt;toString&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="na"&gt;productRoutes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;HandledRoute&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;productIds&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&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;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;route&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`/product/&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;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="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;productRoutes&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;validator&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &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="nf"&gt;registerPlugin&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;product&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;productRoutes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validator&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll also need to update the config file to use the &lt;code&gt;product&lt;/code&gt; plugin:&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;// ./scully.[project].config.ts&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./scully/plugins/plugin&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&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;ScullyConfig&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;projectRoot&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;projectName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PROJECT-NAME-HERE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;outDir&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./dist/static&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;routes&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;/product/:slug&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;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;product&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;Sweet! Now when we run the Scully build with this plugin, Scully will select to pre-render either the product IDs passed as arguments - if there are any - or the returned product IDs of an API call to &lt;code&gt;${environment.api.url}/products&lt;/code&gt;, meaning you have great control over which routes to render.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scully is AWESOME!
&lt;/h2&gt;

&lt;p&gt;We’ve seen how Scully can solve Angular E-Commerce applications' problems in a handful of ways.&lt;/p&gt;

&lt;p&gt;There is little downside to using Scully. The main one is the need to run an extra step between build and deploy, but as shown in this article, you can lower the impact with incremental builds. Needless to say, if you care about lower bounce rates and increasing the likelihood your website will be a top result on search engines, Scully is your friend.&lt;/p&gt;

&lt;p&gt;As a bonus, I’ve setup an &lt;a href="https://e-commerce-scully-example.vercel.app/"&gt;E-Commerce example app&lt;/a&gt; (deployed with &lt;code&gt;ng build &amp;amp;&amp;amp; scully&lt;/code&gt;) where I used Scully to pre-render the content so you can see how the output looks using your browser’s DevTools. And you can compare it with a second &lt;a href="https://e-commerce-no-scully-example.vercel.app/"&gt;E-Commerce no-Scully example app&lt;/a&gt; (deployed with &lt;code&gt;ng build&lt;/code&gt; only), where the Scully pre-render step is not used. By the way, here's the &lt;a href="https://github.com/fabioemoutinho/e-commerce-scully-example"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you need any assistance or you just want to chat with us, you can reach us through our &lt;a href="https://www.bitovi.com/community/slack"&gt;Bitovi Community Slack&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>scully</category>
      <category>seo</category>
      <category>webvitals</category>
    </item>
    <item>
      <title>How to Create Custom ESLint Rules (It's Not as Hard as You Think...)</title>
      <dc:creator>Fábio Englert Moutinho</dc:creator>
      <pubDate>Wed, 09 Feb 2022 19:56:28 +0000</pubDate>
      <link>https://dev.to/bitovi/how-to-create-custom-eslint-rules-its-not-as-hard-as-you-think-3f9f</link>
      <guid>https://dev.to/bitovi/how-to-create-custom-eslint-rules-its-not-as-hard-as-you-think-3f9f</guid>
      <description>&lt;p&gt;Most teams develop patterns or preferred ways of writing code, but it can be tedious to enforce adhering to those patterns, especially for new team members onboarding. To help this, we rely on linters for basic formatting, but did you know you can take preference-enforcement to the next level by writing your own lint rules?&lt;/p&gt;

&lt;p&gt;As TypeScript developers, we use ESLint as it is capable of linting both TypeScript AND JavaScript files.&lt;/p&gt;

&lt;p&gt;I'm going to teach you how to write custom ESLint rules that work for your team.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;⚠️ Disclaimer: the rest of this post contains irony and sarcasm.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But it is probably very hard to code an ESLint rule, right? It sounds like something that only an extremely experienced developer could manage. 👀&lt;/p&gt;

&lt;p&gt;And you are right, it would be very hard - &lt;em&gt;SPOILER: coding is hard&lt;/em&gt; - if ESLint did not provide an awesome API for us.&lt;/p&gt;

&lt;p&gt;So it IS possible to write custom ESLint Rules. But we need a reason to write one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Write a Custom ESLint Rule?
&lt;/h2&gt;

&lt;p&gt;Writing tests is boring. And you are writing tests for things that should work in the first place. Plus, what guarantee do you have that the tests themselves aren't flawed? You'd have to create tests for each test. And then tests for the test tests. You can see where this is leading: nowhere.&lt;/p&gt;

&lt;p&gt;I've now established that tests are bad for your project. We are in &lt;a href="https://gist.github.com/banaslee/4147370"&gt;eXtreme Go Horse&lt;/a&gt; (XGH) territory. &lt;/p&gt;

&lt;p&gt;XGH is clear on the testing matter:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You better know what you are doing. And if you know what you are doing, why test? Tests are a waste of time. If code compiles, it’s enough.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The way to prevent anyone from wasting precious time writing tests is to write your own custom ESLint Rule that screams at you if your project has a .spec file. Sounds good!&lt;/p&gt;

&lt;h2&gt;
  
  
  What to Know Before Writing a Custom ESLint Rule
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;At the end of the day when you are writing a Custom ESLint Rule, you are providing some metadata (&lt;code&gt;meta&lt;/code&gt; property) and callback functions for ESLint to run (&lt;code&gt;create&lt;/code&gt; property). &lt;/li&gt;
&lt;li&gt;create property is a function that returns an object. That object has properties that store the callback functions for ESLint.&lt;/li&gt;
&lt;li&gt;The callback functions represent &lt;code&gt;node types&lt;/code&gt;, &lt;code&gt;selectors&lt;/code&gt;, or &lt;code&gt;events&lt;/code&gt; and they will be triggered by ESLint at some point.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The basic structure of a rule looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt;
  &lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&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="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;&lt;code&gt;context&lt;/code&gt; (on line 3), is an object provided by ESLint that might have useful data or methods you can use in our callback function.&lt;/p&gt;

&lt;p&gt;And that's enough context. 😄&lt;/p&gt;

&lt;h2&gt;
  
  
  Behold the &lt;code&gt;xgh/no-testing&lt;/code&gt; Rule!
&lt;/h2&gt;

&lt;p&gt;Below is the full code for the &lt;code&gt;no-testing&lt;/code&gt; rule object and an explanation of what's going on.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&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="s2"&gt;problem&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;match&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Found '{{filename}}' .spec file. If you knew what you were doing, you wouldn't need to test it.&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="nx"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;context&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="na"&gt;Program&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;filename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getFilename&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
      &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;.spec&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;context&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;report&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;messageId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;match&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;filename&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="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;Inside &lt;code&gt;meta&lt;/code&gt;, you can specify &lt;code&gt;type&lt;/code&gt; (string) as &lt;code&gt;problem&lt;/code&gt;, &lt;code&gt;suggestion&lt;/code&gt;, or &lt;code&gt;layout&lt;/code&gt;. Choose &lt;code&gt;problem&lt;/code&gt; because you want everyone to know that you should not waste time testing.&lt;/p&gt;

&lt;p&gt;At line 9, the &lt;code&gt;create&lt;/code&gt; function will return an object that has a &lt;code&gt;Program&lt;/code&gt; property. That is the top level event that ESLint runs for every file. Read about it &lt;a href="https://eslint.org/docs/developer-guide/code-path-analysis"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Program&lt;/code&gt; property is - you guessed it - a callback function. It takes a &lt;code&gt;node&lt;/code&gt; parameter that you don’t care about, at least not today.&lt;/p&gt;

&lt;p&gt;Here's the interesting part. The “no-testing” logic will kick in: at line 11, you store the current file’s name in a variable. Here the &lt;code&gt;context&lt;/code&gt; comes in handy as it has a &lt;code&gt;getFileName&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;On line 12, check if &lt;code&gt;filename&lt;/code&gt; variable contains the string &lt;code&gt;.spec&lt;/code&gt; in it. If it does, you know it is a test file, so you call the &lt;code&gt;context.report&lt;/code&gt; method to let ESLint know there’s something wrong with our code.&lt;/p&gt;

&lt;p&gt;Lines 15 to 18 forward relevant data as parameters to let ESLint know which message to show. &lt;code&gt;messageId&lt;/code&gt; matches the &lt;code&gt;match&lt;/code&gt; property inside &lt;code&gt;meta.messages&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you want to know more about ESLint Rules, read &lt;a href="https://eslint.org/docs/developer-guide/working-with-rules"&gt;this guide&lt;/a&gt; from ESLint's official documentation. &lt;/p&gt;

&lt;h2&gt;
  
  
  How Do I Use This Wondrous Rule?
&lt;/h2&gt;

&lt;p&gt;You can start using &lt;code&gt;xgh/no-testing&lt;/code&gt; in your project right now!&lt;/p&gt;

&lt;p&gt;Run the command &lt;code&gt;npm i -D eslint-plugin-xgh&lt;/code&gt; to install the ESLint plugin that wraps the &lt;code&gt;no-testing&lt;/code&gt; rule.&lt;/p&gt;

&lt;p&gt;All you have to do now is enable the rule in your project.&lt;/p&gt;

&lt;p&gt;Inside your ESLint config 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="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;plugins&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;xgh&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="s2"&gt;rules&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;xgh/no-testing&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="s2"&gt;error&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="c1"&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 would like to take a closer look at the &lt;code&gt;xgh&lt;/code&gt; eslint plugin, &lt;a href="https://github.com/fabioemoutinho/xgh"&gt;here's the git repository&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  All Kidding Aside...
&lt;/h2&gt;

&lt;p&gt;At Bitovi, we ABSOLUTELY recommend writing unit tests. This tongue-in-cheek post is to show you the possibilities available to better lint your code by writing custom rules. If you need help writing your own rules or learning better coding practices, &lt;a href="https://www.bitovi.com/frontend-javascript-consulting/angular-consulting?hsLang=en-us"&gt;please reach out&lt;/a&gt;!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Originally posted in &lt;a href="https://www.bitovi.com/blog/how-to-create-custom-eslint-rules-its-not-as-hard-as-you-think"&gt;Bitovi Blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>eslint</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>How to Avoid the Infamous "Cannot read properties of undefined" Error with TypeScript</title>
      <dc:creator>Fábio Englert Moutinho</dc:creator>
      <pubDate>Fri, 10 Dec 2021 13:47:46 +0000</pubDate>
      <link>https://dev.to/bitovi/how-to-avoid-the-infamous-cannot-read-properties-of-undefined-error-with-typescript-181h</link>
      <guid>https://dev.to/bitovi/how-to-avoid-the-infamous-cannot-read-properties-of-undefined-error-with-typescript-181h</guid>
      <description>&lt;p&gt;As a JavaScript developer, I’m sure you’ve encountered the frustrating runtime TypeError &lt;code&gt;Cannot read properties of undefined&lt;/code&gt;. TypeScript gives you two ways of interpreting &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; types, also known as Type Check Modes, and one of them can avoid this easily overlooked TypeError.&lt;/p&gt;

&lt;p&gt;Until TypeScript 2.0, there was only one type check mode - regular - and it considers &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; as subtypes of all other types. This means &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; values are valid values for all types.&lt;/p&gt;

&lt;p&gt;TypeScript 2.0 introduced &lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-0.html"&gt;Strict Type Check Mode&lt;/a&gt; (also referred to as strict null checking mode). Strict Type Check differs from Regular Type Check because it considers &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; types of their own.&lt;/p&gt;

&lt;p&gt;I’ll show you how Regular Type Check handles &lt;code&gt;undefined&lt;/code&gt; (the same applies to &lt;code&gt;null&lt;/code&gt;) and how Strict Type Check prevents you from introducing unwanted behavior in our code, like that infamous TypeError &lt;code&gt;Cannot read properties of undefined&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  When undefined becomes a problem
&lt;/h2&gt;

&lt;p&gt;The function translatePowerLevel below takes a number as argument and returns strings &lt;code&gt;one&lt;/code&gt;, &lt;code&gt;two&lt;/code&gt;, &lt;code&gt;many&lt;/code&gt; or &lt;code&gt;it's over 9000!&lt;/code&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;function&lt;/span&gt; &lt;span class="nf"&gt;translatePowerLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;one&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;two&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;9000&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;many&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;9000&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;it&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;s over 9000!&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, this code doesn't handle &lt;code&gt;0&lt;/code&gt;, a valid input - yes, looking at you, Yamcha.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F963s867d7qgl11c8q3qs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F963s867d7qgl11c8q3qs.png" width="384" height="216"&gt;&lt;/a&gt;Yamcha's Power Level&lt;/p&gt;

&lt;p&gt;When JavaScript reaches the end of a function that has no explicit return, it returns &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;translatePowerLevel&lt;/code&gt; function return value is typed explicitly as &lt;code&gt;string&lt;/code&gt;, but it is possibly also returning &lt;code&gt;undefined&lt;/code&gt; when the argument &lt;code&gt;powerLevel&lt;/code&gt; has the value &lt;code&gt;0&lt;/code&gt;. Why is TypeScript not triggering an error?&lt;/p&gt;

&lt;p&gt;In Regular Type Check Mode, TypeScript is aware that a function might return &lt;code&gt;undefined&lt;/code&gt;. But at the same time, TypeScript infers the return type to be only of type string because TypeScript is &lt;a href="https://www.typescriptlang.org/play#example/type-widening-and-narrowing"&gt;widening&lt;/a&gt; the &lt;code&gt;undefined&lt;/code&gt; type to &lt;code&gt;string&lt;/code&gt; type.&lt;/p&gt;

&lt;p&gt;As another example, if you assign &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt; to variables while in Regular Type Check Mode, TypeScript will infer these variables to be of type &lt;code&gt;any&lt;/code&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;coffee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&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;tea&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Interpreting &lt;code&gt;undefined&lt;/code&gt; or &lt;code&gt;null&lt;/code&gt; as subtypes of all other types can lead to runtime problems. For example, if you try to get the length of the result of &lt;code&gt;translateNumber(0)&lt;/code&gt;, which is &lt;code&gt;undefined&lt;/code&gt;, JavaScript will throw this TypeError at runtime: &lt;code&gt;Cannot read properties of undefined (reading 'length')&lt;/code&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;powerLevel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;translatePowerLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&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="c1"&gt;// Uncaught TypeError: Cannot read properties of undefined (reading 'length')&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, TypeScript’s Regular Type Check Mode is not able to alert you to when you may have made that mistake.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strict Type Check Mode to the Rescue
&lt;/h2&gt;

&lt;p&gt;Strict Type Check Mode changes how TypeScript interprets &lt;code&gt;undefined&lt;/code&gt; and &lt;code&gt;null&lt;/code&gt; values. But first, let's enable Strict Type Check Mode.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Enable Strict Type Check Mode in TypeScript
&lt;/h3&gt;

&lt;p&gt;In the root of your project, there should be a &lt;code&gt;tsconfig.json&lt;/code&gt; file. This is the TypeScript’s configuration file and you can read more about it &lt;a href="https://www.typescriptlang.org/docs/handbook/tsconfig-json.html"&gt;here&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="c1"&gt;// tsconfig.json example&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;compilerOptions&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;module&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="s2"&gt;system&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="s2"&gt;noImplicitAny&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;removeComments&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;preserveConstEnums&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;outFile&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="s2"&gt;../../built/local/tsc.js&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="s2"&gt;sourceMap&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;include&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/**/*&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="s2"&gt;exclude&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node_modules&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="s2"&gt;**/*.spec.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside &lt;code&gt;compilerOptions&lt;/code&gt; property, all we need to do is add the property &lt;code&gt;"strictNullChecks": true&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It will look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// tsconfig.json&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;compilerOptions&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;module&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="s2"&gt;system&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="s2"&gt;noImplicitAny&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;removeComments&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;preserveConstEnums&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;outFile&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="s2"&gt;../../built/local/tsc.js&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="s2"&gt;sourceMap&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;strictNullChecks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;include&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;src/**/*&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="s2"&gt;exclude&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;node_modules&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="s2"&gt;**/*.spec.ts&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have switched to Strict Type Check Mode, TypeScript throws this error for &lt;code&gt;translatePowerLevel&lt;/code&gt; function: &lt;code&gt;Function lacks ending return statement and return type does not include 'undefined'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That error message is telling you the function is returning &lt;code&gt;undefined&lt;/code&gt; implicitly, but its return type does not include &lt;code&gt;undefined&lt;/code&gt; in it.&lt;/p&gt;

&lt;p&gt;Awesome! TypeScript is now aware the return type does not match all possible return values, and this could lead to problems at runtime! But how can you match the return type to all possible return values?&lt;/p&gt;

&lt;p&gt;You can either add a return statement so the function always returns a &lt;code&gt;string&lt;/code&gt; (solution #1), or change the return type from string to &lt;code&gt;string | undefined&lt;/code&gt; (solution #2).&lt;/p&gt;

&lt;h3&gt;
  
  
  Match All Possible Return Values: Solution #1
&lt;/h3&gt;

&lt;p&gt;Adding a return statement so it is always explicitly returning a value - in the code below, it is now returning the string &lt;code&gt;zero&lt;/code&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="c1"&gt;// Solution #1: add a return statement so it always returns a string&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;translatePowerLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;one&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;two&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;9000&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;many&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;9000&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;it&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;s over 9000!&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;// new return statement&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;zero&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Match All Possible Return Values: Solution #2
&lt;/h3&gt;

&lt;p&gt;Make the &lt;code&gt;undefined&lt;/code&gt; return type explicit so wherever &lt;code&gt;translatePowerLevel&lt;/code&gt; is used, you have to handle &lt;code&gt;nullish&lt;/code&gt; values as well.&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;// Solution #2: return type as string | undefined&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;translatePowerLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;one&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&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="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;two&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="mi"&gt;9000&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;many&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="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;9000&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;it&lt;/span&gt;&lt;span class="se"&gt;\'&lt;/span&gt;&lt;span class="s1"&gt;s over 9000!&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you were to compile the following code again using Solution #2, TypeScript would throw the error &lt;code&gt;Object is possibly 'undefined'&lt;/code&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;powerLevel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;translatePowerLevel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// undefined&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;powerLevel&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="c1"&gt;// Object is possibly 'undefined'.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you choose a solution like Solution #2, TypeScript expects you to write code that handles possible &lt;code&gt;nullish&lt;/code&gt; values.&lt;/p&gt;

&lt;h2&gt;
  
  
  There’s no reason not to use Strict Type Check Mode
&lt;/h2&gt;

&lt;p&gt;Now you understand how TypeScript interprets &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt; types and how you can migrate your project to Strict Mode.&lt;/p&gt;

&lt;p&gt;If you are starting a new project, you should definitely enable Strict Type Check Mode from the beginning. And in case you will migrate from Regular to Strict Type Check, our team can help with strategies to do so in a less painful way.&lt;/p&gt;

&lt;p&gt;At Bitovi we highly recommend using - or migrating to - Strict Type Check Mode, as it can help you produce better, more reliable code. If you need help with building amazing web apps feel free to reach us at &lt;a href="https://www.bitovi.com/web-application-consulting-services"&gt;bitovi.com&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Originally posted in &lt;a href="https://www.bitovi.com/blog/how-to-avoid-the-infamous-cannot-read-properties-of-undefined-with-typescript"&gt;Bitovi Blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>TypeScript Features Every Angular Developer Needs to Know</title>
      <dc:creator>Fábio Englert Moutinho</dc:creator>
      <pubDate>Mon, 27 Sep 2021 14:33:57 +0000</pubDate>
      <link>https://dev.to/bitovi/typescript-features-every-angular-developer-needs-to-know-4b82</link>
      <guid>https://dev.to/bitovi/typescript-features-every-angular-developer-needs-to-know-4b82</guid>
      <description>&lt;p&gt;If you’re an Angular developer, you’re missing out if you’re not using advanced TypeScript features to help you build better code.&lt;/p&gt;

&lt;p&gt;And it’s well worth the effort: TypeScript has some great features that can make you a stronger Angular developer. 💪&lt;/p&gt;

&lt;h1&gt;
  
  
  BigInt
&lt;/h1&gt;

&lt;p&gt;BigInt lets you represent numbers bigger than 2&lt;sup&gt;53&lt;/sup&gt;. This is useful when you need to perform mathematical operations on very large integers. And you can work directly with large integer IDs and &lt;a href="https://www.smashingmagazine.com/2019/07/essential-guide-javascript-newest-data-type-bigint/"&gt;high resolution timestamps&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can create a &lt;code&gt;bigint&lt;/code&gt; primitive in two ways:&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;n0&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;n&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;n1&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;BigInt&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There is no interoperability between &lt;code&gt;bigint&lt;/code&gt; and &lt;code&gt;number&lt;/code&gt; primitives, but they can be compared.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: BigInt support is only available for the &lt;code&gt;esnext&lt;/code&gt; target.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Numeric Separators _
&lt;/h1&gt;

&lt;p&gt;Numeric separators are great for readability. They don't change how the actual numeric value is interpreted.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt; &lt;span class="c1"&gt;// which one is more readable?&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;someNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1782540173&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;anotherNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;_782_540_173&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;someNumber&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;anotherNumber&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;p&gt;Keep in mind that you can't begin or end a number with a separator. Also, you can't use two in a row.&lt;/p&gt;

&lt;h1&gt;
  
  
  Private Fields
&lt;/h1&gt;

&lt;p&gt;TypeScript has the &lt;code&gt;private&lt;/code&gt; keyword that is stripped out during transpilation to JavaScript. If you need private properties at runtime, JavaScript's private fields come to the rescue. Unlike TypeScript's private keyword, private fields are prepended by a # character and are private even at runtime.&lt;/p&gt;

&lt;p&gt;If you need private properties at runtime, this is now the way to do it in modern JavaScript.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;NOTE: TypeScript will gracefully implement this for older browsers given your target is at least ECMAScript 2015 (ES6).&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&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="nc"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nf"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kr"&gt;public&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;string&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;someone&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;Person&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="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;someone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Property '#age' is not accessible outside class 'Person' because it has a private identifier.&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;someone&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;#age&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt; &lt;span class="c1"&gt;// Property '#age' does not exist on type 'Person'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Operators
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Nullish Coalescing ??
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;In JavaScript, nullish refers to a value strictly equal (&lt;code&gt;===&lt;/code&gt;) to &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A common pattern used in JavaScript when we want a default value is to use the OR operator &lt;code&gt;||&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;function&lt;/span&gt; &lt;span class="nf"&gt;timeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Function&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;milliseconds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="k"&gt;void&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;wait&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;milliseconds&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nf"&gt;setTimeout&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;callback&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;wait&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;Using the OR operator in this way can cause problems. Since we are dealing with numbers in the example above, then the value &lt;code&gt;0&lt;/code&gt; will be a valid &lt;code&gt;milliseconds&lt;/code&gt; value.&lt;br&gt;
However, &lt;code&gt;0&lt;/code&gt; is falsy, so the default value &lt;code&gt;100&lt;/code&gt; will be assigned to &lt;code&gt;wait&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It’s important to distinguish between falsy values (&lt;code&gt;false&lt;/code&gt;, &lt;code&gt;0&lt;/code&gt;, empty string &lt;code&gt;“”&lt;/code&gt;, and &lt;code&gt;null/undefined&lt;/code&gt;) and nullish values (&lt;code&gt;null/undefined&lt;/code&gt;). Nullish values are a subset of falsy values.&lt;/p&gt;

&lt;p&gt;Nullish coalescing is an operator that returns a default value (the second operand) in case the first operand is nullish. If the first operand is not nullish, its value is returned.&lt;/p&gt;

&lt;p&gt;Sounds complicated, but here's a simple example.&lt;/p&gt;

&lt;p&gt;Consider &lt;code&gt;a ?? b&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;will return &lt;code&gt;a&lt;/code&gt; if &lt;code&gt;a&lt;/code&gt; is different than &lt;code&gt;null&lt;/code&gt; and &lt;code&gt;undefined&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;will return &lt;code&gt;b&lt;/code&gt; if &lt;code&gt;a&lt;/code&gt; is equal to &lt;code&gt;null&lt;/code&gt; or &lt;code&gt;undefined&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&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;coffee&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&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;awaken&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;coffee&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;code&gt;awaken&lt;/code&gt; will be assigned either &lt;code&gt;coffee&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;if &lt;code&gt;coffee&lt;/code&gt; is &lt;strong&gt;not nullish&lt;/strong&gt;, &lt;code&gt;awaken&lt;/code&gt; will be assigned &lt;code&gt;coffee&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;if &lt;code&gt;coffee&lt;/code&gt; is nullish, awaken will be assigned &lt;code&gt;false&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Optional Chaining &lt;code&gt;?&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Have you ever seen (or written) code like this?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;prop1&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;prop1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prop2&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;prop1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prop2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prop3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c1"&gt;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Optional chaining changes how objects, properties and methods are accessed. Instead of throwing an error if they are nullish, it will short-circuit and return &lt;code&gt;undefined&lt;/code&gt;. Optional chaining also makes your code more readable.&lt;/p&gt;

&lt;p&gt;This is how we could rewrite the code above with optional chaining:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;obj&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;prop1&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;prop2&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;prop3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="c1"&gt;// do something&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Non Null Assertion &lt;code&gt;!&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Sometimes, TypeScript is unable to identify that some operand is nullish. The non null assertion operator &lt;code&gt;!&lt;/code&gt; comes in handy for those cases. You might use it when you want to tell TypeScript that at that specific point in the code, the operand is definitely not null and not undefined.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// imagine you have a state that represents an API response&lt;/span&gt;
&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nl"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pending&lt;/span&gt;&lt;span class="dl"&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;complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
 &lt;span class="nl"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;State&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;complete&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
 &lt;span class="na"&gt;response&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;some text&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;// we know that when status is 'complete' we must have a response&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;status&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;complete&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="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&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="c1"&gt;// Object is possibly 'undefined'.&lt;/span&gt;
 &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="o"&gt;!&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="c1"&gt;// this works&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check out &lt;a href="https://dev.to/bitovi/non-null-assertion-operator-in-angular-g5l"&gt;this post&lt;/a&gt; by &lt;a href="https://dev.to/likeomgitsfeday"&gt;Jennifer Wadella&lt;/a&gt; to learn more about the non null assertion operator in Angular.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exponentiation **
&lt;/h2&gt;

&lt;p&gt;In 2 &lt;code&gt;**&lt;/code&gt; 3, raises the first operand &lt;code&gt;2&lt;/code&gt; to the power of the second, &lt;code&gt;3&lt;/code&gt;, being equivalent to 2&lt;sup&gt;3&lt;/sup&gt;.&lt;/p&gt;

&lt;p&gt;Contrary to Math.pow(), the exponentiation operator &lt;code&gt;**&lt;/code&gt; works with the new BigInt values.&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;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="o"&gt;**&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pow&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="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; &lt;span class="c1"&gt;// the old way&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Assignment Operators &lt;code&gt;**=&lt;/code&gt;, &lt;code&gt;&amp;amp;&amp;amp;=&lt;/code&gt;, &lt;code&gt;||=&lt;/code&gt;, &lt;code&gt;??=&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Assignment operators are shorthand for common assignment operations. For example, &lt;code&gt;a += 1&lt;/code&gt; is equivalent to &lt;code&gt;a = a + 1&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Assignment operators apply an operator to two arguments, then assign the result to the left operand.&lt;/p&gt;

&lt;p&gt;Additionally, the &lt;code&gt;&amp;amp;&amp;amp;=&lt;/code&gt;, &lt;code&gt;||=&lt;/code&gt;, &lt;code&gt;??=&lt;/code&gt; operators will short-circuit, which means if the operation is evaluated to false, no assignment will occur.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&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="c1"&gt;// a **= b, exponentiation&lt;/span&gt;
&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&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="c1"&gt;// a &amp;amp;&amp;amp;= b, logical AND&lt;/span&gt;
&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&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="c1"&gt;// a ||= b, logical OR&lt;/span&gt;
&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&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="c1"&gt;// a ??= b, nullish coalescing&lt;/span&gt;
&lt;span class="c1"&gt;// a &amp;amp;&amp;amp;= b, also equivalent to:&lt;/span&gt;
&lt;span class="k"&gt;if &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="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;a&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="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// a ||= b, also equivalent to:&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;a&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="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;// a ??= b, also equivalent to:&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="nx"&gt;a&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="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These TypeScript techniques can help you handle nullish values, improve readability, manipulate larger integers, and more. I hope you find these TypeScript features useful for your Angular code!&lt;/p&gt;

&lt;p&gt;To learn more about Angular and TypeScript, check out the &lt;a href="https://www.bitovi.com/academy/"&gt;Bitovi Academy&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Originally posted in &lt;a href="https://www.bitovi.com/blog/typescript-features-every-angular-developer-needs-to-know"&gt;Bitovi Blog&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
