<?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: Erxk</title>
    <description>The latest articles on DEV Community by Erxk (@erxk).</description>
    <link>https://dev.to/erxk</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%2F173178%2F01242003-8f6d-42a7-9bfd-dd26fdbe56a3.jpeg</url>
      <title>DEV Community: Erxk</title>
      <link>https://dev.to/erxk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/erxk"/>
    <language>en</language>
    <item>
      <title>Angular Mastery: Template Syntax</title>
      <dc:creator>Erxk</dc:creator>
      <pubDate>Tue, 01 Oct 2019 10:57:53 +0000</pubDate>
      <link>https://dev.to/erxk_verduin/angular-mastery-template-syntax-b8j</link>
      <guid>https://dev.to/erxk_verduin/angular-mastery-template-syntax-b8j</guid>
      <description>&lt;p&gt;Mastering the Fundamentals of Angular Template Language: Part 1&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Complexity:&lt;/strong&gt; [&lt;strong&gt;Beginner&lt;/strong&gt; , &lt;strong&gt;Intermediate&lt;/strong&gt; , Advanced, Expert]&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Source Code:&lt;/strong&gt; &lt;a href="https://stackblitz.com/edit/erxk-template-syntax"&gt;StackBlitz &lt;strong&gt;🚀&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Article Goal:&lt;/strong&gt; Streamline information from experience and the &lt;a href="https://angular.io/guide/template-syntax"&gt;Angular Documentation&lt;/a&gt; to aid in understanding Angular Template Syntax — Utilizing cheat-sheets, code-examples, and focusing on the essentials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Article Topics (What We’ll Learn):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Expressions &amp;amp; Statements: Guidelines, Rules, and Usages&lt;/li&gt;
&lt;li&gt;Properties &amp;amp; Attributes: How they relate to Data Binding&lt;/li&gt;
&lt;li&gt;Data Binding: Dynamically generating views&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Angular Template Language (ATL)
&lt;/h3&gt;

&lt;p&gt;Angular Template Language is the language used when working with a component-template/html in Angular. We can consider ATL an extension of HTML that allows us to employ &lt;em&gt;Interpolation&lt;/em&gt;, &lt;em&gt;Angular Template Expressions &amp;amp; Statements&lt;/em&gt;, &lt;em&gt;Data Binding&lt;/em&gt;, etc…&lt;/p&gt;

&lt;p&gt;To understand the &lt;em&gt;Angular Template Syntax&lt;/em&gt;, first, we will investigate &lt;em&gt;Angular Template Expressions and Statements&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Expressions &amp;amp; Statements
&lt;/h3&gt;

&lt;p&gt;If you’ve worked with Angular then you’ve likely used an &lt;em&gt;Angular Template&lt;/em&gt; &lt;em&gt;Expression&lt;/em&gt; or &lt;em&gt;Angular Template&lt;/em&gt; S_tatement_ before.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Angular Template Expressions/Statements will be called expressions and statements for short.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;em&gt;Expressions&lt;/em&gt; and &lt;em&gt;statements&lt;/em&gt; are essentially a mini-syntax derived from a subset of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators#Expressions"&gt;JavaScript Expressions&lt;/a&gt;. [Table A] below may help illuminate the context of when we use one or the other.&lt;/p&gt;

&lt;p&gt;Note, in [Table A], &lt;strong&gt;type&lt;/strong&gt; refers to a &lt;em&gt;data binding type&lt;/em&gt;. — We cover &lt;em&gt;data binding&lt;/em&gt; in a later section once we have the necessary context of &lt;em&gt;expressions&lt;/em&gt;, &lt;em&gt;statements&lt;/em&gt;, and &lt;em&gt;properties&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--w3X5w0gz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/780/1%2AaifbepspFomNuLIod1Gsqw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--w3X5w0gz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/780/1%2AaifbepspFomNuLIod1Gsqw.png" alt=""&gt;&lt;/a&gt;Table A&lt;/p&gt;

&lt;h4&gt;
  
  
  Expressions
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Expressions&lt;/em&gt; have their own syntax and general guidelines that should be followed. — &lt;em&gt;Expressions&lt;/em&gt; should be &lt;strong&gt;simple&lt;/strong&gt; , &lt;strong&gt;quick&lt;/strong&gt; , and have &lt;strong&gt;no side-effects&lt;/strong&gt;. These qualities are key to performance. In most cases, &lt;em&gt;expressions&lt;/em&gt; will be evaluated every change detection cycle 🔁.&lt;/p&gt;

&lt;p&gt;The &lt;em&gt;expression&lt;/em&gt; syntax is very similar to JavaScript expressions. — However, there are some limitations to operations that promote side effects. For a &lt;a href="https://angular.io/guide/template-syntax#template-expressions"&gt;complete list see here&lt;/a&gt;, for syntax examples see [Table B]. See &lt;a href="https://stackblitz.com/edit/erxk-template-syntax?file=src%2Fapp%2Fexpression-examples%2Fexpression-examples.component.html"&gt;source code&lt;/a&gt; for corresponding examples of syntax from [Table B].&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hdc2T0Jt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/916/1%2AesDUNMii_dnKA8fy1ANzPg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hdc2T0Jt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/916/1%2AesDUNMii_dnKA8fy1ANzPg.png" alt=""&gt;&lt;/a&gt;Table B&lt;/p&gt;

&lt;p&gt;Note, the above examples all use &lt;em&gt;interpolation&lt;/em&gt; for consistency. — The results would be the same with &lt;em&gt;two-way&lt;/em&gt; [(property)]="expression" and &lt;em&gt;property binding&lt;/em&gt; [property]="expression"; as they all use &lt;em&gt;expressions&lt;/em&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tip: Expressions can utilize a safe-navigation operator to guard against null and undefined &lt;em&gt;[target]="object?.property"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Statements
&lt;/h4&gt;

&lt;p&gt;When working with event-binding () we are utilizing &lt;em&gt;statements&lt;/em&gt;. They should be written in a way that is &lt;strong&gt;simple&lt;/strong&gt; and usually &lt;strong&gt;has a&lt;/strong&gt;  &lt;strong&gt;side-effect&lt;/strong&gt;. &lt;em&gt;Statements&lt;/em&gt; are &lt;em&gt;event-driven&lt;/em&gt;, and &lt;em&gt;events&lt;/em&gt; usually update state/data from a user action; which is why &lt;em&gt;statements&lt;/em&gt; &lt;strong&gt;should&lt;/strong&gt; have side effects.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Statements&lt;/em&gt; can execute potentially long-running operations and various tasks because they &lt;strong&gt;only run when the bound event fires.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Compared to &lt;em&gt;expressions&lt;/em&gt;, similar rules apply to the &lt;a href="https://angular.io/guide/template-syntax#template-statements"&gt;syntax of &lt;em&gt;statements&lt;/em&gt;&lt;/a&gt; with some exceptions. The majority of the time we will simply invoke a method inside of a _statement. — _See [Table C] for syntax examples, see &lt;a href="https://stackblitz.com/edit/erxk-template-syntax?file=src%2Fapp%2Fstatement-examples%2Fstatement-examples.component.ts"&gt;source code&lt;/a&gt; for corresponding examples.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YpGBeWxL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/768/1%2AzAXDATXqFF7qoJAsvf5ecQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YpGBeWxL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/768/1%2AzAXDATXqFF7qoJAsvf5ecQ.png" alt=""&gt;&lt;/a&gt;Table C&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Points
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Unlike s_tatements_, &lt;em&gt;expressions&lt;/em&gt; should &lt;strong&gt;not&lt;/strong&gt; execute complex logic, they should always be quick.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Expressions&lt;/em&gt; can utilize the pipe operator |to chain to Angular Pipes. &lt;em&gt;Statements&lt;/em&gt; utilize ; and , to chain multiple operations/arguments and cannot use Angular Pipes.&lt;/li&gt;
&lt;li&gt;Both &lt;em&gt;expressions&lt;/em&gt; and &lt;em&gt;statements&lt;/em&gt; should be simple, short, and concise.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Properties &amp;amp; Attributes
&lt;/h3&gt;

&lt;p&gt;Before we dive into &lt;em&gt;Angular Data Binding&lt;/em&gt;, we should understand the differences between &lt;a href="https://angular.io/guide/template-syntax#html-attribute-vs-dom-property"&gt;&lt;em&gt;properties&lt;/em&gt; and &lt;em&gt;attributes&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Data Binding&lt;/em&gt; works with &lt;strong&gt;properties&lt;/strong&gt; , not &lt;em&gt;attributes&lt;/em&gt;. Exceptions are &lt;em&gt;attributes&lt;/em&gt; such as &lt;em&gt;aria-*&lt;/em&gt; and &lt;em&gt;svg&lt;/em&gt;. &lt;em&gt;Properties&lt;/em&gt; are read from DOM Nodes, whereas &lt;em&gt;attributes&lt;/em&gt; are read from HTML Elements. &lt;em&gt;Attributes&lt;/em&gt; are used to initialize &lt;em&gt;properties&lt;/em&gt; and do not change.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Caveat, using setAttribute() will change an attribute and re-initialize its corresponding property.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Many &lt;em&gt;attributes&lt;/em&gt; have 1:1 relationship with &lt;em&gt;properties&lt;/em&gt;. For example, on an HTML Input Element, &lt;em&gt;value&lt;/em&gt; is the name of an &lt;em&gt;attribute&lt;/em&gt; and the name of a &lt;em&gt;property&lt;/em&gt;. — The GIF below summarizes the above information in action.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--goJ0jx3R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/448/1%2A8nm5bVp_pThxz3Um18rzQA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--goJ0jx3R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/448/1%2A8nm5bVp_pThxz3Um18rzQA.gif" alt=""&gt;&lt;/a&gt;property “value” changes, attribute “value” does not&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Points
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Angular Data Binding generally works with &lt;strong&gt;properties&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Attributes&lt;/em&gt; and &lt;em&gt;properties&lt;/em&gt; are different things, even when they have the same name&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Attributes&lt;/em&gt; generally do *&lt;em&gt;not *&lt;/em&gt; change&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Data Binding
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://angular.io/guide/template-syntax#binding-syntax-an-overview"&gt;Data Binding&lt;/a&gt; allows us to dynamically set DOM &lt;em&gt;properties&lt;/em&gt; and listen for &lt;em&gt;events&lt;/em&gt; simply by declaring a target element &lt;em&gt;property&lt;/em&gt;/&lt;em&gt;event&lt;/em&gt; and writing an &lt;em&gt;expression&lt;/em&gt;/&lt;em&gt;statement&lt;/em&gt;. — To better understand data binding, we will use native elements such as &lt;em&gt;input&lt;/em&gt; and create our own &lt;em&gt;components&lt;/em&gt; with custom bindings.&lt;/p&gt;

&lt;p&gt;Data Binding has three categories of &lt;strong&gt;data flow&lt;/strong&gt; : &lt;em&gt;source-to-view&lt;/em&gt;, &lt;em&gt;view-to-source&lt;/em&gt;, and &lt;em&gt;two-way&lt;/em&gt; (&lt;em&gt;view-to-source-to-view&lt;/em&gt;).&lt;/p&gt;

&lt;h4&gt;
  
  
  One-Way Binding ( &lt;strong&gt;Source-to-View&lt;/strong&gt; )
&lt;/h4&gt;

&lt;p&gt;When discussing &lt;em&gt;source-to-view&lt;/em&gt; &lt;em&gt;binding&lt;/em&gt; we will focus on &lt;a href="https://angular.io/guide/template-syntax#property-binding-property"&gt;&lt;strong&gt;property binding&lt;/strong&gt;&lt;/a&gt; [property]="expression". As discussed in the previous section, &lt;em&gt;data binding&lt;/em&gt; works primarily with &lt;em&gt;properties&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Collectively, all five [property]="",[class.css-class]="",[style.css-pro]="",[attr.attribute]="", &lt;code&gt;{{interpolation}}&lt;/code&gt; are categorized as &lt;em&gt;source-to-view&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;You may be wondering, where does &lt;em&gt;interpolation&lt;/em&gt; fit into &lt;em&gt;source-to-view&lt;/em&gt; &lt;em&gt;binding&lt;/em&gt;? When using &lt;em&gt;interpolation&lt;/em&gt;, Angular evaluates the &lt;em&gt;expression&lt;/em&gt; and writes the interpolated result to an element &lt;em&gt;property&lt;/em&gt;. — In other words, &lt;strong&gt;Angular converts interpolation into a property binding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As shown in the GIF below, all three examples bind to the &lt;em&gt;textContent property&lt;/em&gt; and produce the same result.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bSCJmLq9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/556/1%2AKE0-aQ8MCQB4-XlZ3cYloA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bSCJmLq9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/556/1%2AKE0-aQ8MCQB4-XlZ3cYloA.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Property bindings&lt;/em&gt; often expect a &lt;strong&gt;specific return type&lt;/strong&gt; based on the target DOM &lt;em&gt;property&lt;/em&gt;. Depending on what type our element/component is expecting, we should return that given type.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;To summarize, we can visualize &lt;em&gt;source-to-view binding&lt;/em&gt; in a username example. Whenever our source properties are updated, the view will reflect those updates on change detection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ga3C_LJh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/556/1%2ARqQT672K8YSXLi5J2yhugQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ga3C_LJh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/556/1%2ARqQT672K8YSXLi5J2yhugQ.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  One-Way Binding (View-to-Source)
&lt;/h4&gt;

&lt;p&gt;View-to-Source, also known as &lt;a href="https://angular.io/guide/template-syntax#event-binding-event"&gt;&lt;strong&gt;Event Binding&lt;/strong&gt;&lt;/a&gt;, connects an &lt;em&gt;event&lt;/em&gt; to a &lt;em&gt;statement&lt;/em&gt;. In other words, when a user fires an action on an element (view-target), it invokes a method inside of our component (data-source)&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Event Binding&lt;/em&gt; is unique in that it provides the &lt;em&gt;template variable&lt;/em&gt; &lt;strong&gt;$event&lt;/strong&gt;. This &lt;em&gt;$event&lt;/em&gt; variable contains all information regarding the &lt;em&gt;event&lt;/em&gt; including any potential updated values.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Using the same username example from earlier, we can visualize our view listening for events and invoking methods from our source on that event.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ruu8y2Sm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/764/1%2AGxh_MgB1DbElWRq_hr5GEA.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ruu8y2Sm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/764/1%2AGxh_MgB1DbElWRq_hr5GEA.gif" alt=""&gt;&lt;/a&gt;$event.target.value abbreviated to $event.value&lt;/p&gt;

&lt;h4&gt;
  
  
  Two-Way Binding (View-to-Source-to-View)
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://angular.io/guide/template-syntax#two-way-binding-"&gt;Two-Way binding&lt;/a&gt; [()], also known as View-to-Source-to-View, is essentially a &lt;strong&gt;shorthand syntax for property binding and event binding together&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Two-Way Binding follows a semantic pattern in the component where an @Input named &lt;strong&gt;x&lt;/strong&gt; and a corresponding @Output named  &lt;strong&gt;xChange.&lt;/strong&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The snippet below shows its usage with the t_wo-way Binding_ syntax, as well as explicit syntax using &lt;em&gt;one-way property binding&lt;/em&gt; and &lt;em&gt;one-way event binding&lt;/em&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The GIF below attempts to shed light on why/when we would utilize &lt;em&gt;two-way binding in a component&lt;/em&gt;. Notice, with only &lt;em&gt;one-way property binding&lt;/em&gt; (second example), the component value is initialized and updates. However, the external value that was passed in does &lt;strong&gt;not&lt;/strong&gt; update when the internal component value updates.&lt;/p&gt;

&lt;p&gt;When only &lt;em&gt;one-way event binding&lt;/em&gt; is in place (third example), the initial value is never set. Changes are seen in the component, but in this case, we cannot increment or decrement undefined; causing NaN to display.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--00islC7H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/446/1%2AdrGATzwXoRiWqjPHikRlNw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--00islC7H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/446/1%2AdrGATzwXoRiWqjPHikRlNw.gif" alt=""&gt;&lt;/a&gt;&lt;em&gt;(countChange)&lt;/em&gt;=”externalValue=$event.target.value”&lt;/p&gt;

&lt;p&gt;Visualizing the data flow in our username example, our source and view now form a complete circle of invoking the &lt;em&gt;class/source&lt;/em&gt; on an event and updating the &lt;em&gt;template/view&lt;/em&gt; on change detection:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--pvSM2vBc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/776/1%2A2yXB0_tcv77Y0kicDkU5TQ.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--pvSM2vBc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://cdn-images-1.medium.com/max/776/1%2A2yXB0_tcv77Y0kicDkU5TQ.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Points
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Data Binding has three directions: Source-to-View (Property Binding)[], View-to-Source (Event Binding)(), and View-to-Source-to-View (Two-Way Binding)[()]&lt;/li&gt;
&lt;li&gt;Property Binding [] &lt;strong&gt;writes&lt;/strong&gt; to the target element&lt;/li&gt;
&lt;li&gt;Event Binding () &lt;strong&gt;listens&lt;/strong&gt; to the target element&lt;/li&gt;
&lt;li&gt;Two-Way Binding [()] is just syntactic sugar for Property + Event Binding.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;We’ve covered the basics of leveraging Angular Template Syntax to create dynamic views. — In the next section, we will cover the attribute directives &lt;em&gt;NgClass&lt;/em&gt; and &lt;em&gt;NgStyle&lt;/em&gt;. Thanks for reading!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9EOOcErN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/438/1%2A0aeUljGBf1ore8nZElWBCA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9EOOcErN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/438/1%2A0aeUljGBf1ore8nZElWBCA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators"&gt;JavaScript Expressions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/template-syntax#interpolation-and-template-expressions"&gt;Expressions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/template-syntax#template-statements"&gt;Statements&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/template-syntax#html-attribute-vs-dom-property"&gt;Properties/Attributes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/template-syntax#binding-syntax-an-overview"&gt;Data Binding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/template-syntax#property-binding-property"&gt;Property Binding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/template-syntax#event-binding-event"&gt;Event Binding&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://angular.io/guide/template-syntax#two-way-binding-"&gt;Two-Way Binding&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




</description>
      <category>webdev</category>
      <category>tutorial</category>
      <category>javascript</category>
      <category>angular</category>
    </item>
    <item>
      <title>Angular &amp; Headless CMS</title>
      <dc:creator>Erxk</dc:creator>
      <pubDate>Mon, 08 Jul 2019 23:10:14 +0000</pubDate>
      <link>https://dev.to/itnext/angular-headless-cms-538p</link>
      <guid>https://dev.to/itnext/angular-headless-cms-538p</guid>
      <description>&lt;h4&gt;
  
  
  Build a Blog with Angular and Contentful
&lt;/h4&gt;

&lt;p&gt;I have built a blog application using Angular and a headless CMS, Contentful. Contentful gives developers and non-developers alike the ability to manage content in a web application. I use Contentful to manage content on my website. — I am not sponsored by Contentful and any headless CMS could be substituted. See alternatives [1]&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blog-demo-5c8d8.web.app" rel="noopener noreferrer"&gt;Live Demo 🌌&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Everduin94/angular-headless-cms" rel="noopener noreferrer"&gt;Download the Source Code 🚀&lt;/a&gt;&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%2Fa7lqjzf8oo2f3tnd8uei.gif" 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%2Fa7lqjzf8oo2f3tnd8uei.gif" width="800" height="450"&gt;&lt;/a&gt;App Overview&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;What is a Headless CMS&lt;/li&gt;
&lt;li&gt;Contentful Basics&lt;/li&gt;
&lt;li&gt;Angular: Accessing &amp;amp; Displaying Content&lt;/li&gt;
&lt;li&gt;Hosting&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What is a Headless CMS
&lt;/h3&gt;

&lt;p&gt;As I learned to build web applications, I heard about Content Management Systems (CMS); such as Wordpress or Drupal. I thought to myself, why would a developer use this if they already knew how to build a website? At the time, I did not understand the need or use-case.&lt;/p&gt;

&lt;p&gt;Later, when I was ready to create my own side-projects and ship them to non-developers, I paused.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How can someone, who is not a developer, update content on my web application?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I had already spent a significant amount of time developing my skill set building front-end applications. Would I now have to learn something like WordPress to build apps?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Headless CMS has entered the chat.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Headless CMS, like Contentful, are essentially web applications that abstract away the database/backend from developers and non-developers alike.&lt;/p&gt;

&lt;p&gt;A headless CMS does &lt;strong&gt;not&lt;/strong&gt; provide a front-end. — They do provide developers with an API to get content from the back-end, and a user interface for non-developers to enter content into the back-end.&lt;/p&gt;

&lt;p&gt;We will build an Angular application to display data and use Contentful to create/manage that data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Contentful Basics
&lt;/h3&gt;

&lt;p&gt;We will cover the basics of Contentful. — For a comprehensive introduction see &lt;a href="https://www.contentful.com/developers/docs/tutorials/" rel="noopener noreferrer"&gt;here [2]&lt;/a&gt;.&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%2Feikv30unagtux07az5c2.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%2Feikv30unagtux07az5c2.png" width="800" height="388"&gt;&lt;/a&gt;Contentful Overview&lt;/p&gt;

&lt;p&gt;As an example, let’s set up a new Space with a Single Content Type in &lt;strong&gt;five steps&lt;/strong&gt;.&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%2Fc93303qdbfdxpujnf4jk.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%2Fc93303qdbfdxpujnf4jk.png" width="471" height="406"&gt;&lt;/a&gt;Top-Left Menu: Create Space&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Create a Space
&lt;/h4&gt;

&lt;p&gt;Getting started is as simple as signing up. — Once signed up, we can create our own Space. As an analogy, we can think of a Space like our own individual database.&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%2F8qjkeepkov9l6nwrsd1j.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%2F8qjkeepkov9l6nwrsd1j.png" width="659" height="520"&gt;&lt;/a&gt;Create a Content Type&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Create a Content Type
&lt;/h4&gt;

&lt;p&gt;We will add a Content Type to our Space. We can think of a Content Type like a table definition in a Database. — A Content Type is not the actual content, just the design.&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%2Fmhboghypbjk4d1mj13j5.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%2Fmhboghypbjk4d1mj13j5.png" width="746" height="530"&gt;&lt;/a&gt;Add Fields to the Content Type&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Create Fields
&lt;/h4&gt;

&lt;p&gt;Now we will add fields to our Content Type. Think of fields like columns in a database table. — In our example, we are creating a blog post, which will have fields such as title, description, body, etc…&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%2Fbgt6kxf5z92qn2jbnr6e.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%2Fbgt6kxf5z92qn2jbnr6e.png" width="800" height="510"&gt;&lt;/a&gt;Create new Content&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Create Content
&lt;/h4&gt;

&lt;p&gt;Each piece of Content we add will be similar to a new row in a database. We will fill out each field we defined earlier in our blogPost Content Type.&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%2F274i78tnpjaujboj2b5v.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%2F274i78tnpjaujboj2b5v.png" width="679" height="462"&gt;&lt;/a&gt;Space ID &amp;amp; Content Delivery Acess Token&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Access the API
&lt;/h4&gt;

&lt;p&gt;In the next section, we will use our Space ID and Content Delivery Access Token to retrieve our Contentful data and display it in our application.&lt;/p&gt;

&lt;h3&gt;
  
  
  Angular: Accessing &amp;amp; Displaying Content
&lt;/h3&gt;

&lt;p&gt;To get started with the Contentful API, we add the following object to our environment.ts file. We enter the information from &lt;strong&gt;step 5&lt;/strong&gt; of Contentful Basics.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  1. Display All Entries of a Content Type
&lt;/h4&gt;

&lt;p&gt;Using cdaClient.getEntries(content_type), we retrieve a promise containing all Content for a specific Content Type. The resolved data is an array of blog posts. Each entry has two properties, fields and sys.&lt;/p&gt;

&lt;p&gt;Sys contains information such as created-date and ID. Fields are the fields we defined in step 3 of Contentful Basics.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Leveraging the Angular Structural Directive, *ngFor, we can dynamically add all blog posts to the DOM. — When we add a new blog post to Contentful, our post will be automatically added by our Contentful Service.&lt;/p&gt;

&lt;p&gt;Using Angular Template Syntax, we can build list items displaying info from our Contentful Service such as createdAt, ID, title, description, etc…&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  2. Display a specific Entry of a Content Type
&lt;/h4&gt;

&lt;p&gt;Using cdaClient.getEntry(id), we can query a specific entry from our Contentful data. The resolved data is a single blog post with the sys and fields properties.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;When a user clicks one of the containers from the first section, the router navigates to a dynamic route /posts/:id. In snippet 1.2, we passed the ID as a parameter via routerLink.— We can retrieve the ID from Angular’s ActivatedRoute paramMap.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Contentful provides a Markdown editor for all text fields. We will leverage this by converting the Markdown to HTML and setting the inner HTML on a div. &lt;a href="https://fireship.io/" rel="noopener noreferrer"&gt;[4]&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use innerHTML judiciously, If we do not have full control over what is being entered into the innerHTML we need to sanitize the input to &lt;a href="https://angular.io/api/platform-browser/DomSanitizer" rel="noopener noreferrer"&gt;prevent xss-attacks [5]&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Using Angular’s Structural Directive, *ngIf, we can optionally display a field if it exists. In our example, we will display a link to an original publication if present.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Add a New Contentful Entry
&lt;/h4&gt;

&lt;p&gt;After publishing a new Contentful Entry, our application is immediately updated on refresh with the latest Content. — No changes are needed to our Angular project.&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%2Fprnr3kr3esqgp5m66dle.gif" 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%2Fprnr3kr3esqgp5m66dle.gif" width="780" height="600"&gt;&lt;/a&gt;Final Product&lt;/p&gt;

&lt;h3&gt;
  
  
  Hosting
&lt;/h3&gt;

&lt;p&gt;The live demo is hosted with Firebase. For directions on hosting a project with Firebase see &lt;a href="https://www.youtube.com/watch?v=aICeVhu2mAE" rel="noopener noreferrer"&gt;here [6]&lt;/a&gt;. For alternative forms of hosting see here [7].&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am not affiliated with or sponsored by Firebase or any of the alternatives.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Resources &amp;amp; References
&lt;/h3&gt;

&lt;p&gt;[1] &lt;a href="https://www.sanity.io/" rel="noopener noreferrer"&gt;Sanity&lt;/a&gt; | &lt;a href="https://flamelink.io/?gclid=CjwKCAjwsIbpBRBNEiwAZF8-z2vWGi3LO1o6EqAg8Mh9njo35Y5F5l464KcCz7yK0-hPjtg9GuLcKxoC7jgQAvD_BwE" rel="noopener noreferrer"&gt;FlameLink&lt;/a&gt; | &lt;a href="https://www.sitepoint.com/wordpress-headless-cms/" rel="noopener noreferrer"&gt;Headless Wordpress&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2] &lt;a href="https://www.contentful.com/developers/docs/tutorials/" rel="noopener noreferrer"&gt;Contentful-Tutorial&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[3] &lt;a href="https://angular.io/guide/structural-directives" rel="noopener noreferrer"&gt;Structural-Directives&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[4] Learned the Markdown-to-HTML Technique on &lt;a href="https://fireship.io/" rel="noopener noreferrer"&gt;fireship&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[5] &lt;a href="https://angular.io/api/platform-browser/DomSanitizer" rel="noopener noreferrer"&gt;DOM Sanitizer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[6] &lt;a href="https://www.youtube.com/watch?v=aICeVhu2mAE" rel="noopener noreferrer"&gt;Host with Firebase&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[7] &lt;a href="https://www.netlify.com/" rel="noopener noreferrer"&gt;Netlify&lt;/a&gt; | &lt;a href="https://aws.amazon.com/" rel="noopener noreferrer"&gt;AWS&lt;/a&gt; | &lt;a href="https://www.digitalocean.com/" rel="noopener noreferrer"&gt;Digital Ocean&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Improve Performance with Web Workers</title>
      <dc:creator>Erxk</dc:creator>
      <pubDate>Tue, 18 Jun 2019 11:23:52 +0000</pubDate>
      <link>https://dev.to/erxk/improve-performance-with-web-workers-186g</link>
      <guid>https://dev.to/erxk/improve-performance-with-web-workers-186g</guid>
      <description>&lt;h4&gt;
  
  
  Using the Angular 8 CLI
&lt;/h4&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;This article will illustrate how to improve start-up performance using Web Workers. Our example will be an Angular 8 application. Using the Angular 8 CLI simplifies getting started with Web Workers. However, using Web Workers is not specific to Angular and most of these concepts can be utilized in any Javascript or Typescript application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Everduin94/Web-Worker-Demo"&gt;Download the Source Code 🚀&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will cover&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Measuring Performance in Lighthouse&lt;/li&gt;
&lt;li&gt;Getting Started with Web Workers in Angular 8 &lt;a href="https://angular.io/guide/web-worker"&gt;[1]&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Measuring Performance with Web Workers&lt;/li&gt;
&lt;li&gt;Web Worker Limitations and Pitfalls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--9uuxN5tR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/799/1%2APjG4nKh1rPSMM1WWCjoRVw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--9uuxN5tR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/799/1%2APjG4nKh1rPSMM1WWCjoRVw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Measuring Performance with Lighthouse
&lt;/h3&gt;

&lt;p&gt;First, we need to get a baseline measurement to gauge how performant our application is on start-up without a Web Worker. Note, we are running our Angular application in production mode — This affects start-up performance.&lt;/p&gt;

&lt;p&gt;In the Google Chrome Developer Tools 🛠, using Lighthouse, we can measure the performance of our webpage on startup &lt;a href="https://developers.google.com/web/tools/lighthouse/"&gt;[2]&lt;/a&gt;. I have added a long-running task/computation to the startup of our application (for-loop building a massive string).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yy2ci1WD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/807/1%2A3y3QeULKPgDahlxnkJRPIg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yy2ci1WD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/807/1%2A3y3QeULKPgDahlxnkJRPIg.png" alt=""&gt;&lt;/a&gt;Performance without Web Worker&lt;/p&gt;

&lt;p&gt;When we execute a long-running task on the Main thread, our application appears to be locked up. This is because the Main thread is blocked by all of the computations in our long-running task. Thus, the user cannot interact with our application until the process has finished.&lt;/p&gt;

&lt;p&gt;By clicking “View Trace”, we can see a visualization of CPU time on start-up. In our example, the majority of the time spent was evaluating/running our script/task. We can also verify in the trace that our code is running in the Main thread.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--DZ0jEssK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/782/1%2A9VaeYW8_mHbjNYfm5kIjPw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--DZ0jEssK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/782/1%2A9VaeYW8_mHbjNYfm5kIjPw.png" alt=""&gt;&lt;/a&gt;Performance without Web Worker&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting Started with Web Workers
&lt;/h3&gt;

&lt;p&gt;The Angular 8 CLI has simplified getting started with Web Workers. To create a Web Worker, we will simply run the Angular 8 web-worker schematic.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sU17JR8P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/659/1%2A6chGmXLlZ2MqkhAPhDxdBg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sU17JR8P--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/659/1%2A6chGmXLlZ2MqkhAPhDxdBg.png" alt=""&gt;&lt;/a&gt;Generate a Web Worker&lt;/p&gt;

&lt;p&gt;The name and location of the worker are mostly arbitrary. A caveat, if your Web Worker has the same name and folder as your component, Angular will automatically add the following code to your component for you. If not, add this code where you want to use the worker.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The only other code generated is the actual worker itself. &lt;strong&gt;This is where we will move our long-running computations to.&lt;/strong&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Main thread → Web Worker → Main thread
&lt;/h4&gt;

&lt;p&gt;When our Web Worker invokes worker.postMessage('hello') the content inside our 'message' event listener will execute inside the Worker. Once our task has completed, postMessage(response) will be called from the Web Worker and worker.onmessage(data)=&amp;gt; {} will execute inside our component back in the Main thread.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  Web Worker Performance
&lt;/h3&gt;

&lt;p&gt;Once we move our long-running task to the Web Worker inside of addEventListener('message', (data)=&amp;gt; { // Here }); we will be ready to test our performance again. Note, we will cover various limitations when executing code in a Web Worker later. For now, we simply move our code from the component to the Web Worker.&lt;/p&gt;

&lt;p&gt;We can see that the performance of our application on start-up has significantly improved. This is because the Main thread only takes 1.8s before its finished evaluating our Javascript and rendering our components on the screen.&lt;/p&gt;

&lt;p&gt;When our long-running task was in the Main thread, we had to wait the additional time to complete the long-running task before the application became interactive.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_SK8w-AS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/805/1%2AWicKvygJstaTr58HL26sJg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_SK8w-AS--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/805/1%2AWicKvygJstaTr58HL26sJg.png" alt=""&gt;&lt;/a&gt;Performance with Web Worker&lt;/p&gt;

&lt;p&gt;The application stays interactive the entire time our script/task is running, as it is &lt;strong&gt;not&lt;/strong&gt; on the Main thread. Performing a “View Trace” we can verify that our script/task is running in an instance of our Worker and the Main thread is sitting idle.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MYegOn8l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/699/1%2APHCuB5C0gq034xHCxrYDJw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MYegOn8l--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/699/1%2APHCuB5C0gq034xHCxrYDJw.png" alt=""&gt;&lt;/a&gt;Performance with Web Worker&lt;/p&gt;

&lt;h3&gt;
  
  
  Web Worker Limitations &amp;amp; Pitfalls
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Cannot Pass Functions to Web Workers
&lt;/h4&gt;

&lt;p&gt;Functions and methods cannot be passed to Web Workers. When an object is passed to a Web Worker, all of its methods are removed. If a function is passed to a web worker, the following exception will occur.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;worker.postMessage(() =&amp;gt; {return 'hello'});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OCtrTYzq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/982/1%2AYp92KYXiTePEkM3lnqHi-g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OCtrTYzq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/982/1%2AYp92KYXiTePEkM3lnqHi-g.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Working with DOM &amp;amp; window
&lt;/h4&gt;

&lt;p&gt;Web Workers run in a different global context than window. DOM manipulation is not allowed, and some methods and properties of the window are not available in web workers. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers"&gt;[3]&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Ca2Gux5g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/833/1%2ASQ_No-02vDWyKKFN-HcbRw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Ca2Gux5g--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/833/1%2ASQ_No-02vDWyKKFN-HcbRw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Running very large processes
&lt;/h4&gt;

&lt;p&gt;In general, there is not a significant difference in time to complete a task when running in Main or in a Web Worker. If you run very large processes inside of a Web Worker, there is a point where the Web Worker becomes significantly slower than the Main thread.&lt;/p&gt;

&lt;p&gt;In our example, if we increase the number of iterations significantly, we can see the difference in performance changes dramatically.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vUsnYAf9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AP00wlIWQj_Vhx12qFmgWPQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vUsnYAf9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AP00wlIWQj_Vhx12qFmgWPQ.png" alt=""&gt;&lt;/a&gt;Smaller Dataset: 19ms | 37ms&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IxfY7gvk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AQUreHbRoJCTNedzD_dDpmg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IxfY7gvk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AQUreHbRoJCTNedzD_dDpmg.png" alt=""&gt;&lt;/a&gt;Larger Dataset: 13s | 39s&lt;/p&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Measure the performance of an application on start-up using Lighthouse in Google Chrome Developer Tools.&lt;/li&gt;
&lt;li&gt;Long-running tasks/computations in the Main thread will cause the UI to lock and become unresponsive&lt;/li&gt;
&lt;li&gt;Delegate long-running tasks to Web Workers to improve performance&lt;/li&gt;
&lt;li&gt;Angular 8 CLI simplifies getting started with Web Workers&lt;/li&gt;
&lt;li&gt;Be aware of limitations and pitfalls when working with Web Workers&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;[1] &lt;a href="https://angular.io/guide/web-worker"&gt;https://angular.io/guide/web-worker&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2] &lt;a href="https://developers.google.com/web/tools/lighthouse/"&gt;https://developers.google.com/web/tools/lighthouse/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[3] &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers"&gt;https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>What Makes a Great Programming/Technical Article?</title>
      <dc:creator>Erxk</dc:creator>
      <pubDate>Thu, 13 Jun 2019 13:04:19 +0000</pubDate>
      <link>https://dev.to/erxk/what-makes-a-great-programming-technical-article-a65</link>
      <guid>https://dev.to/erxk/what-makes-a-great-programming-technical-article-a65</guid>
      <description>&lt;p&gt;What do you look for when considering if a programming/technical article is great? What style of technical articles do you prefer? Tips and tricks, tutorials, how-tos, etc...&lt;/p&gt;

&lt;p&gt;For myself, I value when the article has a repository associated with it so I can download the source code or examples. If the information provided is backed-up by examples and the writing is clear and concise I usually consider that a great article. &lt;/p&gt;

&lt;p&gt;I'm also a sucker for good charts and graphs 📊&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>writing</category>
    </item>
    <item>
      <title>Angular &amp; RxJS: Detecting Memory Leaks</title>
      <dc:creator>Erxk</dc:creator>
      <pubDate>Mon, 27 May 2019 14:02:27 +0000</pubDate>
      <link>https://dev.to/erxk/angular-rxjs-detecting-memory-leaks-48nl</link>
      <guid>https://dev.to/erxk/angular-rxjs-detecting-memory-leaks-48nl</guid>
      <description>&lt;p&gt;I’ve built a sample Angular application using RxJS to simulate various memory leaks. The majority of these techniques apply to any component-based framework using RxJS.&lt;/p&gt;

&lt;p&gt;You can download the source code here: &lt;a href="https://github.com/Everduin94/memory-leaks-rxjs"&gt;&lt;strong&gt;https://github.com/Everduin94/memory-leaks-rxjs&lt;/strong&gt;&lt;/a&gt; 🚀&lt;/p&gt;

&lt;p&gt;We’ll cover:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Strategies for detecting a memory leak&lt;/li&gt;
&lt;li&gt;Unsubscribe and Garbage Collection&lt;/li&gt;
&lt;li&gt;Solutions to resolve subscription-based memory leaks&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Strategies For Detecting A Memory Leak
&lt;/h3&gt;

&lt;p&gt;Using Google Chrome Developer Tools 🛠 (Ctrl+Shift+I) In Google Chrome&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dByTQIuA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/642/1%2AVdpx6qWXaG8Vgr612FlMSg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dByTQIuA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/642/1%2AVdpx6qWXaG8Vgr612FlMSg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Allocation Timeline 📈&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Allocation Timelines allow us to see if the minimum size of our heap is growing over time. We’ll start with a baseline before creating or destroying any components.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2MHmIzCW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/789/1%2A1wJuyDE4eSxijssxdP8UKg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2MHmIzCW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/789/1%2A1wJuyDE4eSxijssxdP8UKg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now while the timeline is running, we’ll create/destroy the LargeLeak Component multiple times. Note, I’ve typed large into the filter as we are looking for allocations of the LargeLeakComponent&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jM4QcgnN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Allr0aXPbsxkingnCbJ_WSg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jM4QcgnN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Allr0aXPbsxkingnCbJ_WSg.png" alt=""&gt;&lt;/a&gt;LargeLeakComponent.ts&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jKbxAz-w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/792/1%2ABO3vR8RBXPWLFV0qjTsf9g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jKbxAz-w--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/792/1%2ABO3vR8RBXPWLFV0qjTsf9g.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we return to our starting point (destroy LargeLeakComponent) → manually run garbage collection (🗑 garbage-can icon in the top left) → and restart the allocation timeline (⚫ circle icon in the top left). We can see our minimum heap size has increased and the allocations are not being released.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--C5WNHYLR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/782/1%2AnBu2ckm9fsFgEgDTOfuEZw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--C5WNHYLR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/782/1%2AnBu2ckm9fsFgEgDTOfuEZw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Heap Snapshot 📸&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;The heap snapshot is useful once we’ve identified a leak. Unlike allocation timelines 🐌, a heap snapshot won’t cause latency while we interact with our app. Ultimately, both snapshot and allocation timeline can be used to detect leaks.&lt;/p&gt;

&lt;p&gt;We’ll start with a heap snapshot before doing anything in our application. This will be our baseline or starting point. We can see 0 ServiceObservableLeak Components have been allocated.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uoEaqslg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AoZswZXkVnYbHLQEfKK417w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uoEaqslg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AoZswZXkVnYbHLQEfKK417w.png" alt=""&gt;&lt;/a&gt;ServiceObservableLeak.ts&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PfF1Mzkh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/787/1%2AAdn3R1c5QUmygfjhN1F_uA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PfF1Mzkh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/787/1%2AAdn3R1c5QUmygfjhN1F_uA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After toggling creation/destruction multiple times → manually running garbage collection 🗑→ and taking another snapshot ⚫. We can see that the component is not being released via garbage collection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--3rjoz7M---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/798/1%2AJwsguLButwYr3KpMpymzsQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--3rjoz7M---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/798/1%2AJwsguLButwYr3KpMpymzsQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note, searching for just the component is not always an effective method for finding a memory leak. If we assume there is a memory leak, we should also inspect the number of subscribers in memory. 🔍 Using the snapshot comparison (Dropdown next to filter), we can compare two separate snapshots. This shows us we’ve allocated 30 subscribers and deleted 0. More on this in “Unsubscribe and Garbage Collection”.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PSBleDN9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/910/1%2ADCa53K2eFIaHJL9f5d8Abw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PSBleDN9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/910/1%2ADCa53K2eFIaHJL9f5d8Abw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Unsubscribe and Garbage Collection&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;It’s commonly mentioned that subscriptions hold a reference to the component. Thus, the component cannot be released, creating a memory leak. Not being able to release either object referencing each other is known as a cycle. &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management"&gt;[1]&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Cycles are a limitation of the “Reference-counting garbage collection” algorithm. Modern browsers utilize a “Mark-and-sweep” algorithm 🎯. Mark and Sweep algorithms will collect all non-reachable objects from the root (Global Object). This solves the limitations of cycles.&lt;/p&gt;

&lt;p&gt;We can validate this idea of cycles being handled by the garbage collector by testing with a local finite observable. As we toggle the local-finite component → manually run garbage collection 🗑→ take a heap snapshot ⚫.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZsC8Jiu8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AOlBEXQdubKn1SVmEJvKYRQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZsC8Jiu8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AOlBEXQdubKn1SVmEJvKYRQ.png" alt=""&gt;&lt;/a&gt;FiniteObservableComponent.ts&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--599Z9_Uy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/797/1%2Ak0xqb0-41cnJzSwIBoxksQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--599Z9_Uy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/797/1%2Ak0xqb0-41cnJzSwIBoxksQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can see that the component is not leaking, even though we have not used a subscription management strategy (such as unsubscribe).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;”So I can just let garbage collection manage my subscriptions?”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;No.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PCDyaHB3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/noiqrwv2m5su9mayim7p.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PCDyaHB3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/noiqrwv2m5su9mayim7p.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If the subscription/component still has some reference back to the root, it will not be garbage collected. We can see this in our ServiceObservableLeak Component from the previous example. Since our observable (observable$) is allocated in a service (SourceService), the component still has a reference back to the root via the observable. We need to unsubscribe for the component (ServiceObservableLeakComponent) to be available for garbage collection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ySc0K2Ey--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/726/1%2AB_TxSruza9lrfFtZLPdjBw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ySc0K2Ey--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/726/1%2AB_TxSruza9lrfFtZLPdjBw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not managing subscriptions is a bad practice and should be avoided. Take the FromEvent Component for example. The component initializes a local observable that is watching for click events on a button within FromEventComponent.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jxo3ocX9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AkFLR2OrVSsqrc6z5SpWHJQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jxo3ocX9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AkFLR2OrVSsqrc6z5SpWHJQ.png" alt=""&gt;&lt;/a&gt;FromEventComponent.ts&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Txm4plkd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/919/1%2ANh5DWQ0OtThb0EiUD6_2mg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Txm4plkd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/919/1%2ANh5DWQ0OtThb0EiUD6_2mg.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this example, the component is being released but the subscriber is not. To make the situation more complicated, the subscriber only leaks when the click event has been fired at least once. This creates a memory leak that is very difficult to track down. — The solution is to always manage your subscriptions.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Solutions&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6QBCYKiJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/q25altwpke5zxqse3xmf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6QBCYKiJ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/q25altwpke5zxqse3xmf.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I plan to write in more detail on these methods in a future article. For now, here’s a high-level overview. 🌎&lt;/p&gt;

&lt;h4&gt;
  
  
  Unsubscribe
&lt;/h4&gt;

&lt;p&gt;Unsubscribing to all subscriptions in the ngOnDestroy method is a valid strategy. This is similar to what the async pipe does under the hood on a component-level.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qvxOw8qW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AePafZp5DswpHRrjgxZM-lw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qvxOw8qW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2AePafZp5DswpHRrjgxZM-lw.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Async Pipe
&lt;/h4&gt;

&lt;p&gt;Will manage your subscription based on the life of the DOM element it’s associated with. Async pipe will make a new subscription wherever it’s declared. Use “as” to re-use the value provided.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8W_gWnUD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Ah_gZJTcdaB39ejXkRQZnxQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8W_gWnUD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2Ah_gZJTcdaB39ejXkRQZnxQ.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Take
&lt;/h4&gt;

&lt;p&gt;take, takeUntil, and takeWhile will all manage a subscription automatically based on a condition being met. For example, takeUntil will take an observable as an argument and maintain a subscription until that observable emits a value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--502pfCEw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A6_XXCKo_cdGswxhwNyf55w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--502pfCEw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/1024/1%2A6_XXCKo_cdGswxhwNyf55w.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;Resources / References&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;[1]: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management"&gt;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Syntax-highlighted images are generated by &lt;a href="https://carbon.now.sh/"&gt;https://carbon.now.sh&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>angular</category>
      <category>rxjs</category>
      <category>webdev</category>
      <category>chrome</category>
    </item>
  </channel>
</rss>
