<?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: Budi Irawan</title>
    <description>The latest articles on DEV Community by Budi Irawan (@deerawan).</description>
    <link>https://dev.to/deerawan</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%2F206066%2Fb2cfa761-2df4-4d79-ad01-c17166045b82.jpeg</url>
      <title>DEV Community: Budi Irawan</title>
      <link>https://dev.to/deerawan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/deerawan"/>
    <language>en</language>
    <item>
      <title>What other ways to enforce immutability in Angular beside using Immutable.js?</title>
      <dc:creator>Budi Irawan</dc:creator>
      <pubDate>Wed, 27 Oct 2021 00:20:40 +0000</pubDate>
      <link>https://dev.to/deerawan/what-other-ways-to-enforce-immutability-in-angular-beside-using-immutablejs-416k</link>
      <guid>https://dev.to/deerawan/what-other-ways-to-enforce-immutability-in-angular-beside-using-immutablejs-416k</guid>
      <description>&lt;p&gt;If we use &lt;code&gt;OnPush&lt;/code&gt; change detection strategy, immutability is helpful to ensure change detection works expectedly. &lt;/p&gt;

&lt;h2&gt;
  
  
  Problem in Immutable.js
&lt;/h2&gt;

&lt;p&gt;One of the way to enforce immutability is using &lt;code&gt;Immutable.js&lt;/code&gt;. However, using &lt;code&gt;Immutable.js&lt;/code&gt; is not really straightforward. It adds another layer instead of using JS object directly e.g&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;apps&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;([{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slack&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;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;skype&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}]);&lt;/span&gt;
&lt;span class="nx"&gt;apps&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// { name: 'slack' }&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Map&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// 'slack'&lt;/span&gt;

&lt;span class="c1"&gt;// Using Record if we want to access property directly&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AppRecord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;AppRecord&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;props&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;newApp&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;App&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;slack&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;newApp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 'slack'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have to use &lt;code&gt;get&lt;/code&gt; when using &lt;code&gt;List&lt;/code&gt; and &lt;code&gt;Map&lt;/code&gt;. Using &lt;code&gt;Record&lt;/code&gt; could solve the issue, but if we have a very large object, using &lt;code&gt;Record&lt;/code&gt; will be hard to maintain because we need to create each record per object and it's nested object.&lt;/p&gt;

&lt;p&gt;Other issue is about JS compatibility because it needs to use &lt;code&gt;fromJS&lt;/code&gt; and &lt;code&gt;toJS&lt;/code&gt; methods to convert from and to JS object. &lt;/p&gt;

&lt;p&gt;I'd say that I'm not a fan of that lib and it makes things more complicated. &lt;/p&gt;

&lt;p&gt;Other possible approach I'm thinking of: &lt;/p&gt;

&lt;h2&gt;
  
  
  TS &lt;code&gt;readonly&lt;/code&gt; + ESLint immutable
&lt;/h2&gt;

&lt;p&gt;Since Angular using Typescript, let's use &lt;code&gt;Readonly&amp;lt;T&amp;gt;&lt;/code&gt;, &lt;code&gt;ReadonlyArray&lt;/code&gt; to enforce immutability. &lt;/p&gt;

&lt;p&gt;Also add this &lt;code&gt;no-mutation&lt;/code&gt; ESLint rule as extra protection &lt;a href="https://github.com/jonaskello/eslint-plugin-functional/blob/master/docs/rules/immutable-data.md"&gt;https://github.com/jonaskello/eslint-plugin-functional/blob/master/docs/rules/immutable-data.md&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;is there any better approach? &lt;/p&gt;

&lt;p&gt;Thank you&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>angular</category>
    </item>
    <item>
      <title>Can SPA be used for building a public directory site with SEO support?</title>
      <dc:creator>Budi Irawan</dc:creator>
      <pubDate>Sat, 10 Oct 2020 08:19:02 +0000</pubDate>
      <link>https://dev.to/deerawan/can-spa-be-used-for-building-a-public-directory-site-with-seo-support-4bhj</link>
      <guid>https://dev.to/deerawan/can-spa-be-used-for-building-a-public-directory-site-with-seo-support-4bhj</guid>
      <description>&lt;p&gt;Hi everyone, &lt;/p&gt;

&lt;p&gt;I'm planning to create a directory website similar to &lt;a href="https://yelp.com"&gt;Yelp&lt;/a&gt; or &lt;a href="https://www.yellowpages.com"&gt;Yellow Page&lt;/a&gt; that support SEO for popular search engines and also social media preview. &lt;/p&gt;

&lt;p&gt;My current SPA (Single Page Application) framework is Angular. I've been building some internal Angular apps (don't care about SEO), but this time I got this initiative to build one for the public. I've explored some options to add SEO support for Angular. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Angular Universal&lt;/strong&gt; =&amp;gt; I have done spike for this one but I feel that it will be hard to maintain code for universal rendering. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Rendertron&lt;/strong&gt; =&amp;gt; seems great but worry about infrastructure cost and also wondering if it is scalable. &lt;a href="https://github.com/GoogleChrome/rendertron"&gt;Rendertron link&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Looking at Yelp and Yellow Page, seems they are not built using SPA, maybe Python or PHP. It questions me whether this kind of public website is not the best case for SPA.&lt;/p&gt;

&lt;p&gt;Do you have any suggestions about the approach that I should take? Do we have an example of a successful SPA for a public website? &lt;/p&gt;

&lt;p&gt;Thank you in advance&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>angular</category>
    </item>
    <item>
      <title>Covid-19 Stats Chrome Extension - Angular</title>
      <dc:creator>Budi Irawan</dc:creator>
      <pubDate>Thu, 07 May 2020 12:38:34 +0000</pubDate>
      <link>https://dev.to/deerawan/covid-19-stats-chrome-extension-angular-24bb</link>
      <guid>https://dev.to/deerawan/covid-19-stats-chrome-extension-angular-24bb</guid>
      <description>&lt;p&gt;Hi everyone, I want to share my Chrome extension to display Covid-19 statistics.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://chrome.google.com/webstore/detail/covid-19-stats/pjfcgnbgefoebpppegbmjigihbjmoijj" rel="noopener noreferrer"&gt;Download link&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/deerawan/covid-19-stats" rel="noopener noreferrer"&gt;Github repository&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Screenshots
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqhwoa1h1bmg0msxeimvk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fqhwoa1h1bmg0msxeimvk.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tech stack:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Angular 9&lt;/li&gt;
&lt;li&gt;Jest&lt;/li&gt;
&lt;li&gt;Cypress &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Things learned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This is actually my first Chrome extension 😬 so it's been a great experience&lt;/li&gt;
&lt;li&gt;CSS variables for switching light and dark mode&lt;/li&gt;
&lt;li&gt;Github Actions to run Jest and Cypress (I used to use Travis CI)&lt;/li&gt;
&lt;li&gt;I used Figma to design the UI (I used to use Sketch)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Hope you guys like it&lt;/p&gt;

</description>
      <category>angular</category>
      <category>javascript</category>
    </item>
    <item>
      <title>DOM Property vs HTML Attribute in Property Binding</title>
      <dc:creator>Budi Irawan</dc:creator>
      <pubDate>Sun, 22 Sep 2019 02:42:05 +0000</pubDate>
      <link>https://dev.to/deerawan/dom-property-vs-html-attribute-in-property-binding-48e4</link>
      <guid>https://dev.to/deerawan/dom-property-vs-html-attribute-in-property-binding-48e4</guid>
      <description>&lt;p&gt;To gain more understanding of how Angular property binding works, we need to know the differences between DOM Property and HTML attributes. Property binding is a way to display a value comes from component to template. &lt;/p&gt;

&lt;p&gt;If we have this ordinary HTML,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/input&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and if we want to bind a property to that in Angular, we wrap &lt;code&gt;value&lt;/code&gt; with square brackets &lt;code&gt;[&lt;/code&gt; and &lt;code&gt;]&lt;/code&gt; such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;[value]=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/input&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have &lt;code&gt;value&lt;/code&gt; and &lt;code&gt;[value]&lt;/code&gt;. Regardless of the brackets, they look exactly the same but they are different things. &lt;/p&gt;

&lt;p&gt;What you must know is&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In the first code, &lt;code&gt;value&lt;/code&gt; is an HTML attribute. See &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#Attributes" rel="noopener noreferrer"&gt;HTML Input&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;In the second code, &lt;code&gt;value&lt;/code&gt; in &lt;code&gt;[value]&lt;/code&gt; is a DOM property. See &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement" rel="noopener noreferrer"&gt;HTMLInputElement&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So, what Angular does in property binding is always target DOM property, &lt;em&gt;not&lt;/em&gt; HTML attribute.&lt;/p&gt;

&lt;p&gt;Does HTML attribute always have 1:1 mapping with DOM property?&lt;/p&gt;

&lt;p&gt;The answer is no.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Some of them have 1:1 mapping e.g &lt;code&gt;value&lt;/code&gt;, &lt;code&gt;name&lt;/code&gt;, &lt;code&gt;type&lt;/code&gt;, &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;src&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Some of them have 1:1 mapping with different name e.g. &lt;code&gt;tabindex vs tabIndex&lt;/code&gt;, &lt;code&gt;rowspan vs rowSpan&lt;/code&gt;, &lt;code&gt;colspan vs colSpan&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Some exist only in HTML attribute e.g. &lt;code&gt;role&lt;/code&gt;, &lt;code&gt;aria&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Some exist only in DOM property e.g. &lt;code&gt;textContent&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Custom Property
&lt;/h1&gt;

&lt;p&gt;Angular allows us to have custom property either from directive or component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;[ngStyle]=&lt;/span&gt;&lt;span class="s"&gt;"{'font-size': fontSize}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;ngStyle&lt;/code&gt; is a custom property comes from Angular directive. Others such as &lt;code&gt;ngClass&lt;/code&gt;, &lt;code&gt;ngIf&lt;/code&gt; and etc. &lt;/p&gt;

&lt;p&gt;Example for a custom component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;student-list&lt;/span&gt; &lt;span class="na"&gt;[students]=&lt;/span&gt;&lt;span class="s"&gt;"students"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/student-list&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;students&lt;/code&gt; is a custom property from component named &lt;code&gt;StudentList&lt;/code&gt; that we have below&lt;/p&gt;

&lt;p&gt;&lt;code&gt;student-list.component.ts&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="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;student-list&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;StudentList&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;students&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;Angular read from &lt;code&gt;@Input&lt;/code&gt; of that component so it'll recognize &lt;code&gt;students&lt;/code&gt; property.&lt;/p&gt;

&lt;p&gt;The default behavior of Angular in property binding will always look for&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Custom property from directive or component&lt;/li&gt;
&lt;li&gt;DOM property&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If Angular couldn't find the property from those two, it will trigger an error, for example we are trying to specify unknown property &lt;code&gt;initial&lt;/code&gt; like below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;value=&lt;/span&gt;&lt;span class="s"&gt;"name"&lt;/span&gt; &lt;span class="na"&gt;[initial]=&lt;/span&gt;&lt;span class="s"&gt;"initialValue"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvkmh5vct27atvfxgwcej.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Fvkmh5vct27atvfxgwcej.jpg" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Property binding in Angular always targets to DOM property instead of HTML attribute. In order to support custom property, Angular will look for custom property from directive or component then DOM property. &lt;/p&gt;

</description>
      <category>angular</category>
    </item>
    <item>
      <title>3 Different Ways to Use Input Decorator</title>
      <dc:creator>Budi Irawan</dc:creator>
      <pubDate>Sat, 07 Sep 2019 20:54:53 +0000</pubDate>
      <link>https://dev.to/deerawan/3-different-ways-to-use-input-decorator-4b3c</link>
      <guid>https://dev.to/deerawan/3-different-ways-to-use-input-decorator-4b3c</guid>
      <description>&lt;p&gt;Input (&lt;code&gt;@Input()&lt;/code&gt;) is one of the most used decorators in Angular apps. It is used to pass data from the parent or host component to the child component. This decorator has a relation with DOM property in the template where the child component is used. &lt;/p&gt;

&lt;p&gt;There are three different ways to use this decorator. &lt;/p&gt;

&lt;h1&gt;
  
  
  1) Plain
&lt;/h1&gt;

&lt;p&gt;This is the basic way to use Input decorator. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;child-one.component.ts&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;message&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;child-one.component.html&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;message&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;

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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;parent.component.html&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="nt"&gt;&amp;lt;child-one&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;"hi there"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/child-one&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2gc718u6kmo0a0wsw1y1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2gc718u6kmo0a0wsw1y1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have a variable named &lt;code&gt;message&lt;/code&gt; and we give it &lt;code&gt;@Input()&lt;/code&gt; decorator for that variable. The DOM property in the template &lt;code&gt;parent-component.html&lt;/code&gt; will use the same name as the variable name. &lt;/p&gt;

&lt;h1&gt;
  
  
  2) Alias
&lt;/h1&gt;

&lt;p&gt;By using an alias, the DOM property in the template can use different name. To give alias, we can give an argument in Input decorator such as &lt;code&gt;@Input('my-alias-naming')&lt;/code&gt;. Below is the example: &lt;/p&gt;

&lt;p&gt;&lt;code&gt;child-two.component.ts&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nx"&gt;message&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;child-two.component.html&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;message&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&amp;gt; &amp;lt;!-- still uses `message` --&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;

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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;parent.component.html&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="nt"&gt;&amp;lt;child-two&lt;/span&gt; &lt;span class="na"&gt;msg=&lt;/span&gt;&lt;span class="s"&gt;"hi there"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/child-two&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- use alias 'msg' --&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2gc718u6kmo0a0wsw1y1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F2gc718u6kmo0a0wsw1y1.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, we give an alias &lt;code&gt;msg&lt;/code&gt; in Input decorator to &lt;code&gt;message&lt;/code&gt; variable. In the child component template (&lt;code&gt;child-component.html&lt;/code&gt;), we still refer to it as &lt;code&gt;message&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HOWEVER,&lt;/strong&gt; in the parent component template (&lt;code&gt;parent-component.html&lt;/code&gt;), we refer to it using its alias &lt;code&gt;msg&lt;/code&gt;. &lt;/p&gt;

&lt;h1&gt;
  
  
  3) Setter Getter
&lt;/h1&gt;

&lt;p&gt;Using the same previous examples, consider that we want to display the &lt;code&gt;message&lt;/code&gt; in uppercase. &lt;/p&gt;

&lt;p&gt;This is probably the common way&lt;/p&gt;

&lt;p&gt;&lt;code&gt;child.component.ts&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;message&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="nf"&gt;ngOnInit&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt; &lt;span class="o"&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;message&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&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;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&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;or, another approach is using &lt;code&gt;uppercase&lt;/code&gt; pipe&lt;/p&gt;

&lt;p&gt;&lt;code&gt;child.component.ts&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;message&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;child.component.html&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;{{ message | uppercase }}&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- using uppercase pipe --&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Well, there's another way by using &lt;code&gt;set&lt;/code&gt; and &lt;code&gt;get&lt;/code&gt; from the Typescript class. They are known as &lt;strong&gt;auto-properties&lt;/strong&gt; which are used to access the class variable and we can execute some logic there. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;child-three.component.ts&lt;/code&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;private&lt;/span&gt; &lt;span class="nx"&gt;_message&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="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="c1"&gt;// specify Input decorator here&lt;/span&gt;
&lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputMessage&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="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;_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputMessage&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;inputMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// uppercase message here&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nf"&gt;message&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;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;_message&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;child-three.component.html&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;p&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;message&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/p&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;

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

&lt;/div&gt;

&lt;p&gt;&lt;code&gt;parent.component.html&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="nt"&gt;&amp;lt;child-three&lt;/span&gt; &lt;span class="na"&gt;message=&lt;/span&gt;&lt;span class="s"&gt;"hi there"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/child-three&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Output&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4n84ywxr58s04xphbfnq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fthepracticaldev.s3.amazonaws.com%2Fi%2F4n84ywxr58s04xphbfnq.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As seen in the code, we define logic to uppercase the message in the &lt;code&gt;set&lt;/code&gt; method. &lt;/p&gt;

&lt;p&gt;Can we still give an alias using this way? Yes, we can specify alias too such as&lt;/p&gt;

&lt;p&gt;&lt;code&gt;child-three.component.ts&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;msg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// give alias&lt;/span&gt;
&lt;span class="kd"&gt;set&lt;/span&gt; &lt;span class="nf"&gt;message&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputMessage&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="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;_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;inputMessage&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;inputMessage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toUpperCase&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// uppercase message here&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;parent.component.html&lt;/code&gt;&lt;/p&gt;


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

&lt;p&gt;&lt;span class="nt"&gt;&amp;lt;child-three&lt;/span&gt; &lt;span class="na"&gt;msg=&lt;/span&gt;&lt;span class="s"&gt;"hi there"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/child-three&amp;gt;&lt;/span&gt; &lt;span class="c"&gt;&amp;lt;!-- use alias 'msg' --&amp;gt;&lt;/span&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h1&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Demo&lt;br&gt;
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://stackblitz.com/edit/2019-09-07-input-decorator" rel="noopener noreferrer"&gt;Demo on Stackblitz&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;Three different ways to use Input decorator. They are plain, alias and &lt;code&gt;set&lt;/code&gt; &lt;code&gt;get&lt;/code&gt; method. Plain way is the most basic way, the DOM property will have the same name as the variable name. The alias way gives us the flexibility to have different DOM property name. Lastly, &lt;code&gt;set&lt;/code&gt; and &lt;code&gt;get&lt;/code&gt; allow us to execute some logic. &lt;/p&gt;

</description>
      <category>angular</category>
    </item>
    <item>
      <title>Using ng-content for Content Projection</title>
      <dc:creator>Budi Irawan</dc:creator>
      <pubDate>Sat, 31 Aug 2019 01:45:07 +0000</pubDate>
      <link>https://dev.to/deerawan/using-ng-content-for-content-projection-56lg</link>
      <guid>https://dev.to/deerawan/using-ng-content-for-content-projection-56lg</guid>
      <description>&lt;p&gt;Content projection is a useful technique in Angular to modify component content. Let's learn it from a very simple scenario. &lt;/p&gt;

&lt;p&gt;You have a button component &lt;code&gt;button.component.ts&lt;/code&gt; using &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; and currently, the text used there is &lt;code&gt;submit&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;button.component.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;Component&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/core&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;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-button&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="s2"&gt;`
    &amp;lt;button class="primary-button"&amp;gt;
      submit
    &amp;lt;/button&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styles&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;.primary-button { background: #94FEB1; padding: 10px; }&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="nx"&gt;AppButtonComponent&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;

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



&lt;p&gt;Then we use that component twice in the HTML template of &lt;code&gt;app component&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app.component.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;app-button&amp;gt;&amp;lt;/app-button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;app-button&amp;gt;&amp;lt;/app-button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



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

&lt;p&gt;It will definitely show two buttons with &lt;code&gt;submit&lt;/code&gt; text.  &lt;/p&gt;

&lt;p&gt;How can we customize the text for that component? Let's say I want to display &lt;code&gt;login&lt;/code&gt; text for the first button and &lt;code&gt;register&lt;/code&gt; for the second one. &lt;/p&gt;

&lt;p&gt;One approach is just to use &lt;code&gt;@Input&lt;/code&gt; so, the text can be passed as property as such&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app.component.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;app-button&lt;/span&gt; &lt;span class="na"&gt;[text]=&lt;/span&gt;&lt;span class="s"&gt;"login"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/app-button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;app-button&lt;/span&gt; &lt;span class="na"&gt;[text]=&lt;/span&gt;&lt;span class="s"&gt;"register"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/app-button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That's not too bad but we can try another approach using &lt;code&gt;ng-content&lt;/code&gt;. To use it, we put &lt;code&gt;&amp;lt;ng-content&amp;gt;&amp;lt;/ng-content&amp;gt;&lt;/code&gt; as replacement of &lt;code&gt;submit&lt;/code&gt; text. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;button.component.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"primary-button"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ng-content&amp;gt;&amp;lt;/ng-content&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then in the HTML template&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app.component.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;app-button&amp;gt;&lt;/span&gt;login&lt;span class="nt"&gt;&amp;lt;/app-button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;app-button&amp;gt;&lt;/span&gt;register&lt;span class="nt"&gt;&amp;lt;/app-button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Woah, this looks familiar like &lt;code&gt;&amp;lt;button&amp;gt;&lt;/code&gt; HTML tag. See that the inner content of &lt;code&gt;&amp;lt;app-button&amp;gt;&lt;/code&gt; are projected into the &lt;code&gt;&amp;lt;ng-content&amp;gt;&amp;lt;/ng-content&amp;gt;&lt;/code&gt; that we define in the HTML template of button component. &lt;/p&gt;

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

&lt;p&gt;That is a single content projection. Interestingly, we can also use &lt;code&gt;ng-content&lt;/code&gt; for multi-content projection. &lt;/p&gt;

&lt;h1&gt;
  
  
  Multi-content Projection
&lt;/h1&gt;

&lt;p&gt;Let's say we have a new component named &lt;strong&gt;Banner&lt;/strong&gt;. It looks like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="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;Component&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/core&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;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-banner&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="s2"&gt;`
    &amp;lt;div class="banner"&amp;gt;
      &amp;lt;div class="banner-title"&amp;gt;
        title
      &amp;lt;/div&amp;gt;
      &amp;lt;div class="banner-description"&amp;gt;
        description        
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styles&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;.banner { background: #C1FDFE; padding: 10px; border: 1px solid #333 }&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.banner-title { font-weight: bold; font-size: 20px; color: #5D83FE }&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;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;AppBannerComponent&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;app.component.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;app-banner&amp;gt;&amp;lt;/app-banner&amp;gt;&lt;/span&gt;

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



&lt;p&gt;Here is when it is displayed&lt;/p&gt;

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

&lt;p&gt;Notice that we have a blue color for &lt;code&gt;title&lt;/code&gt; and black color for &lt;code&gt;description&lt;/code&gt;. What we're trying to do is to use &lt;code&gt;ng-content&lt;/code&gt; to modify &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;description&lt;/code&gt; in the banner component. &lt;/p&gt;

&lt;p&gt;You must think that it should be easy to solve by adding it like below&lt;/p&gt;

&lt;p&gt;&lt;code&gt;banner.component.ts&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"banner"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"banner-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ng-content&amp;gt;&amp;lt;/ng-content&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"banner-description"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ng-content&amp;gt;&amp;lt;/ng-content&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

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



&lt;p&gt;Then&lt;/p&gt;

&lt;p&gt;&lt;code&gt;app.component.html&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;app-banner&amp;gt;&lt;/span&gt; 
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Black Friday Discount&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;p&amp;gt;&lt;/span&gt;50% discount for specific products&lt;span class="nt"&gt;&amp;lt;/p&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/app-banner&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;And this what happened&lt;/p&gt;

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

&lt;p&gt;Can you spot something wrong? Yes, our banner title is not shown in blue color. Apparently, if we have multiple &lt;code&gt;ng-content&lt;/code&gt; specified in the template, Angular will only use the latest defined one. In our case, it will only replace &lt;code&gt;ng-content&lt;/code&gt; in &lt;code&gt;banner-description&lt;/code&gt;.We should project title and description to correct place. &lt;/p&gt;

&lt;p&gt;To solve this, &lt;code&gt;ng-content&lt;/code&gt; has a property named &lt;code&gt;select&lt;/code&gt;. If you specify &lt;code&gt;select&lt;/code&gt; with a CSS matching selector, it will get only the elements matching the selector from the passed in content.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"banner"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"banner-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ng-content&lt;/span&gt; &lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;"h1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ng-content&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"banner-description"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;ng-content&lt;/span&gt; &lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;"p"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ng-content&amp;gt;&lt;/span&gt;       
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;for &lt;code&gt;banner-title&lt;/code&gt;, we target &lt;code&gt;h1&lt;/code&gt; tag, and for &lt;code&gt;banner-description&lt;/code&gt;, we're looking for &lt;code&gt;p&lt;/code&gt; tag from the passed content. &lt;/p&gt;

&lt;p&gt;And the result will be&lt;/p&gt;

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

&lt;p&gt;This is what we want. Awesome! &lt;/p&gt;

&lt;p&gt;Remember that &lt;code&gt;select&lt;/code&gt; property accepts CSS selector, so you can also use class or any valid CSS selector, for example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ng-content&lt;/span&gt; &lt;span class="na"&gt;select=&lt;/span&gt;&lt;span class="s"&gt;".my-title"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ng-content&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://stackblitz.com/edit/20190831-ng-content"&gt;Code example on Stackblitz&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;ng-content&lt;/code&gt; is a way to pass content into a component. It has &lt;code&gt;select&lt;/code&gt; property that allows us to have multiple content projection. &lt;/p&gt;

&lt;p&gt;Hope this article is useful!&lt;/p&gt;

</description>
      <category>angular</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
