<?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: Martin McWhorter</title>
    <description>The latest articles on DEV Community by Martin McWhorter (@martinmcwhorter).</description>
    <link>https://dev.to/martinmcwhorter</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%2F143643%2F957cd937-e48b-4ed0-a2cf-fa8cdb726705.jpeg</url>
      <title>DEV Community: Martin McWhorter</title>
      <link>https://dev.to/martinmcwhorter</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/martinmcwhorter"/>
    <language>en</language>
    <item>
      <title>Extending Angular Material Theme System: Additional Shades</title>
      <dc:creator>Martin McWhorter</dc:creator>
      <pubDate>Fri, 16 Apr 2021 11:39:35 +0000</pubDate>
      <link>https://dev.to/martinmcwhorter/extending-angular-material-theme-system-additional-shades-3pf9</link>
      <guid>https://dev.to/martinmcwhorter/extending-angular-material-theme-system-additional-shades-3pf9</guid>
      <description>&lt;p&gt;In &lt;a href="https://dev.to/martinmcwhorter/extending-angular-material-theme-system-n50"&gt;Part 1&lt;/a&gt; of this series, we discussed how the Angular Material theme system is a powerful tool that may seem overly opinionated. In reality it is very extendable. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the previous example we added a palette to the theme. &lt;/li&gt;
&lt;li&gt;In this example we will add additional named hues to palettes. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Angular Material gives you a &lt;code&gt;lighter&lt;/code&gt; and &lt;code&gt;darker&lt;/code&gt; named color in each palette -- but these may not be enough for your organization or project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;  &lt;span class="nt"&gt;mat-color&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;lighter&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;mat-color&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;darker&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are going to add additional helpers &lt;code&gt;extra-light&lt;/code&gt; and &lt;code&gt;extra-dark&lt;/code&gt;. First we are going to go over a few fundamentals. &lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Detour
&lt;/h2&gt;

&lt;p&gt;Quick definitions of hue, tint, shade and tone. &lt;/p&gt;

&lt;p&gt;Hue = a pure color. &lt;br&gt;
Tint = hue + white&lt;br&gt;
Shade = hue + black&lt;br&gt;
Tone = hue + grey &lt;/p&gt;

&lt;p&gt;A hue is a mix of primary colors (red, blue and green are the primary colors of light, where red, yellow and blue are the primary colors of pigment). Tints, shades and tones vary to give gradients.&lt;/p&gt;
&lt;h2&gt;
  
  
  Theme Palettes
&lt;/h2&gt;

&lt;p&gt;Let's look at a theme pallets and see how they work. &lt;/p&gt;

&lt;p&gt;Each palette starts as a map (like a dictionary or array) of shades and tints, with a key starting from &lt;code&gt;50&lt;/code&gt; to &lt;code&gt;900&lt;/code&gt; going from brightest to darkest -- then &lt;code&gt;A100&lt;/code&gt; to &lt;code&gt;A700&lt;/code&gt; with a gamma shift into pastel tints.&lt;/p&gt;

&lt;p&gt;Then a key of &lt;code&gt;contrast&lt;/code&gt; containing another map containing a text contrast shade or tint for each of the keys.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nv"&gt;$mat-red&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#ffebee&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#ffcdd2&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#ef9a9a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#e57373&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="m"&gt;400&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#ef5350&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="m"&gt;500&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#f44336&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#e53935&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#d32f2f&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="m"&gt;800&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#c62828&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="m"&gt;900&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#b71c1c&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;A100&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#ff8a80&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;A200&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#ff5252&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;A400&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#ff1744&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;A700&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mh"&gt;#d50000&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;contrast&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$dark-primary-text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$dark-primary-text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;200&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$dark-primary-text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;300&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$dark-primary-text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;400&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$dark-primary-text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;500&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$light-primary-text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;600&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$light-primary-text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$light-primary-text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;800&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$light-primary-text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="m"&gt;900&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$light-primary-text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;A100&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$dark-primary-text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;A200&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$light-primary-text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;A400&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$light-primary-text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;A700&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$light-primary-text&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A palette is then created by passing this map to the &lt;code&gt;mat-palette(..)&lt;/code&gt; (being renamed to &lt;code&gt;define-palette(..)&lt;/code&gt;) function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-palette&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$base-palette&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$mat-red&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$lighter&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$darker&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Adding additional helpers
&lt;/h2&gt;

&lt;p&gt;We are now going to extend the &lt;code&gt;mat-pallete()&lt;/code&gt; (or &lt;code&gt;define-palette()&lt;/code&gt;) function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@function&lt;/span&gt; &lt;span class="nf"&gt;my-palette&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$base-palette&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$default&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;500&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$lighter&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$darker&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$extra-light&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$extra-dark&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;900&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$default&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;$new-palette&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-palette&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$base-palette&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$default&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$lighter&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$darker&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$default&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nv"&gt;$extra-palette&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;extra-light&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;map-get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$base-palette&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$extra-light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;extra-dark&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;map-get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$base-palette&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$extra-dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;extra-light-contrast&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-contrast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$base-palette&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$extra-light&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;extra-dark-contrast&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-contrast&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$base-palette&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$extra-dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;@return&lt;/span&gt; &lt;span class="nf"&gt;map_merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$new-palette&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$extra-palette&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can update our example above and get a palette with the &lt;code&gt;extra-light&lt;/code&gt; and &lt;code&gt;extra-dark&lt;/code&gt; helpers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;my-palette&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nv"&gt;$base-palette&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$mat-red&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
  &lt;span class="nv"&gt;$lighter&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
  &lt;span class="nv"&gt;$darker&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;700&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
  &lt;span class="nv"&gt;$extra-light&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;50&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; 
  &lt;span class="nv"&gt;$extra-dark&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="m"&gt;900&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

&lt;span class="nv"&gt;$light-theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-light-theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// elsewhere in a component theme &lt;/span&gt;
&lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;some-theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$theme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;map-get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$theme&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nv"&gt;$primary-lighter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;lighter&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nv"&gt;$primary-darker&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;darker&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nv"&gt;$primary-extra-light&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extra-light&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nv"&gt;$primary-extra-dark&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;extra-dark&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;There we have it. Designers and developers can use &lt;code&gt;extra-light&lt;/code&gt; and &lt;code&gt;extra-dark&lt;/code&gt; as named shades or tints in designs and implementations.&lt;/p&gt;

&lt;p&gt;Your use case will likely be different. You can suit these techniques to your own situation. &lt;/p&gt;

</description>
      <category>angular</category>
      <category>angularmaterial</category>
      <category>theming</category>
      <category>scss</category>
    </item>
    <item>
      <title>Generate Angular ReactiveForms from Swagger/OpenAPI</title>
      <dc:creator>Martin McWhorter</dc:creator>
      <pubDate>Sat, 01 Aug 2020 20:10:30 +0000</pubDate>
      <link>https://dev.to/martinmcwhorter/generate-angular-reactiveforms-from-swagger-openapi-35h9</link>
      <guid>https://dev.to/martinmcwhorter/generate-angular-reactiveforms-from-swagger-openapi-35h9</guid>
      <description>&lt;p&gt;Angular ReactiveForms, &lt;a href="https://alex-klaus.com/stongly-typed-angular-forms/" rel="noopener noreferrer"&gt;despite their problems&lt;/a&gt;, are a powerful tool for encoding form validation rules reactively. &lt;/p&gt;

&lt;h2&gt;
  
  
  Single Source of Truth for Validation Rules
&lt;/h2&gt;

&lt;p&gt;Your backend code should be the single source of truth for validation rules. Of course we should validate input in the UI for a better user experience.&lt;/p&gt;

&lt;p&gt;Likely we are either implementing the same rules from the same spec, or copying what has been implemented in the API, or layers behind that. We should be asking ourselves, &lt;strong&gt;Where should the single source of truth for validation rules live?&lt;/strong&gt; It probably shouldn't be in the Angular app. We can eliminate this manual duplication by generating Angular ReactiveForms from OpenAPI/Swagger specs, rather than hand coding them. &lt;/p&gt;

&lt;p&gt;This eliminates bugs where the validation rules between the UI and API fall out of sync -- or copied incorrectly from the backend to the frontend. When new validation rules change, just rerun the command to generate the reactive form from the updated OpenAPI spec.&lt;/p&gt;

&lt;p&gt;This works very well in conjunction with Rest API proxies generated using the &lt;a href="https://github.com/OpenAPITools/openapi-generator-cli" rel="noopener noreferrer"&gt;openapi-generator&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisite
&lt;/h2&gt;

&lt;p&gt;If your projects do not meet following prerequisite, you can still use the Quick Start. &lt;/p&gt;

&lt;p&gt;In order for this to work with your Rest API you will need to have your backend provide a well formed Swagger (OpenAPI 2) or OpenAPI 3 spec that includes model-metadata for validation expressed as &lt;code&gt;type&lt;/code&gt;, &lt;code&gt;format&lt;/code&gt;, &lt;code&gt;pattern&lt;/code&gt;, &lt;code&gt;minLength&lt;/code&gt;, &lt;code&gt;maxLength&lt;/code&gt;, etc. Frameworks such as SwashbuckleCore and SpringFox (and many others) do this for you based on metadata provided using attributes or annotations.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Quick Start
&lt;/h2&gt;

&lt;p&gt;This quick start uses a hosted swagger spec, so if you can still go through it whether or not your API exposes the required model-metadata.&lt;/p&gt;

&lt;p&gt;First, let's create a new app. &lt;/p&gt;

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

npm i &lt;span class="nt"&gt;-g&lt;/span&gt; @angular/cli
ng n example
&lt;span class="nb"&gt;cd &lt;/span&gt;example


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

&lt;/div&gt;

&lt;p&gt;Second, install the generator into your Angular project as a dev dependancy. &lt;/p&gt;

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

npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; @verizonconnect/ngx-form-generator


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

&lt;/div&gt;

&lt;p&gt;Third, update your &lt;code&gt;package.json&lt;/code&gt; &lt;code&gt;scripts&lt;/code&gt; to include a script to generate the form. This way when the API changes we can easily rerun this script to regenerate the form. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
 &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="w"&gt; 
  &lt;/span&gt;&lt;span class="nl"&gt;"scripts"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; 
  &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"generate:address-form"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ngx-form-generator -i https://raw.githubusercontent.com/verizonconnect/ngx-form-generator/master/demo/swagger.json -o src/app/"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;p&gt;Now run the script. &lt;/p&gt;

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

npm run generate:address-form


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

&lt;/div&gt;

&lt;p&gt;Within your &lt;code&gt;src/app&lt;/code&gt; you will now have a new generated file based on the name of the OpenAPI &lt;code&gt;title&lt;/code&gt; property, in this case &lt;code&gt;myApi.ts&lt;/code&gt;. You can change this using the &lt;code&gt;-f&lt;/code&gt; argument and provide the filename you like. &lt;/p&gt;

&lt;p&gt;We can now import the form into a component and expose it to the template. &lt;/p&gt;

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

&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addressModelForm&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;./myApi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;- import the form&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;app-root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;templateUrl&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.component.html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;styleUrls&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;./app.component.scss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;addressForm&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;addressModelForm&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;- expose form to template&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We will add Angular Material to our project to provide styles for our form in this example. Of course there is no dependency on any CSS or component library.&lt;/p&gt;

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

ng add @angular/material


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

&lt;/div&gt;

&lt;p&gt;In the module lets import &lt;code&gt;ReactiveFormModule&lt;/code&gt;, &lt;code&gt;MatFormFieldModule&lt;/code&gt; and &lt;code&gt;MatInputModule&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;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BrowserModule&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@angular/platform-browser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;NgModule&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;AppComponent&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./app.component&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BrowserAnimationsModule&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/platform-browser/animations&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ReactiveFormsModule&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/forms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;- ESM imports start&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MatFormFieldModule&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/material/form-field&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;MatInputModule&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/material/input&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;NgModule&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;declarations&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;AppComponent&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;imports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="nx"&gt;BrowserModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;BrowserAnimationsModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;ReactiveFormsModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// &amp;lt;- NgModule imports start&lt;/span&gt;
    &lt;span class="nx"&gt;MatFormFieldModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;MatInputModule&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="na"&gt;bootstrap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;AppComponent&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppModule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We will build the form. For demonstration purposes only need the first field. &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;form&lt;/span&gt; &lt;span class="na"&gt;[formGroup]=&lt;/span&gt;&lt;span class="s"&gt;"addressForm"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;mat-form-field&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;mat-label&amp;gt;&lt;/span&gt;First Name&lt;span class="nt"&gt;&amp;lt;/mat-label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;matInput&lt;/span&gt; &lt;span class="na"&gt;formControlName=&lt;/span&gt;&lt;span class="s"&gt;"firstName"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;mat-error&lt;/span&gt; &lt;span class="na"&gt;*ngIf=&lt;/span&gt;&lt;span class="s"&gt;"addressForm.controls.firstName.invalid"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;This field is invalid&lt;span class="nt"&gt;&amp;lt;/mat-error&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/mat-form-field&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;We can now run this with &lt;code&gt;ng serve&lt;/code&gt; and see our single field form. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F3nue2w72wrixcmakfioe.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%2F3nue2w72wrixcmakfioe.png" alt="Empty Field"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An invalid name can be entered into the field and we will see this validated based on the validation rules from exposed to the Angular application through the OpenAPI spec. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fktaodi35qnu9hftl1lcw.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%2Fktaodi35qnu9hftl1lcw.png" alt="Invalid Field"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here we can enter a valid name and see that the validation updates. &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%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fr1vc9m68v55jail5cqp0.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%2Fr1vc9m68v55jail5cqp0.png" alt="Valid Field"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If this were a real RestAPI we could add the rest of our form fields and go. &lt;/p&gt;

&lt;h2&gt;
  
  
  Isolate Generated Code into a Library
&lt;/h2&gt;

&lt;p&gt;We can improve this by putting the generated form into its own library within the Angular workspace. The benefits of this are: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clear separation of boundaries between the generated and crafted code. One of the power-dynamics of generating API proxies and forms is being able to safely regenerate them. This will help prevent a team-member from manually modifying the generated form.
&lt;/li&gt;
&lt;li&gt;No need to recompile the form during local development. The form project will only need to be recompiled when after it has been regenerated. &lt;/li&gt;
&lt;li&gt;We can add this generation process as part of the CICD build process. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Create a new library&lt;/p&gt;

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

ng g lib address-form


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

&lt;/div&gt;

&lt;p&gt;We can now remove the scaffolded component, service and module from the lib. &lt;/p&gt;

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

&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-fr&lt;/span&gt; projects/address-form/src/lib/&lt;span class="k"&gt;*&lt;/span&gt; 


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

&lt;/div&gt;

&lt;p&gt;We are placing only generated code into this library. We do not want to create unit tests for generated code. Tests should live with the code generator itself. So lets get rid of the unit test support files. &lt;/p&gt;

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

&lt;span class="nb"&gt;rm &lt;/span&gt;projects/address-form/karma.conf.js
&lt;span class="nb"&gt;rm &lt;/span&gt;projects/address-form/tsconfig.spec.json
&lt;span class="nb"&gt;rm &lt;/span&gt;projects/address-form/src/test.ts


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

&lt;/div&gt;

&lt;p&gt;We don't need to lint generated code, so lets get rid of tslint.json&lt;/p&gt;

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

&lt;span class="nb"&gt;rm &lt;/span&gt;projects/address-form/tslint.json


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

&lt;/div&gt;

&lt;p&gt;We need to remove the references to the test and lint files in the workspace &lt;code&gt;angular.json&lt;/code&gt;. Open &lt;code&gt;angular.json&lt;/code&gt; and find &lt;code&gt;"address-form": {&lt;/code&gt; property. Remove the &lt;code&gt;"test": {&lt;/code&gt; and &lt;code&gt;"lint": {&lt;/code&gt; sections. &lt;/p&gt;

&lt;p&gt;It should then look something like this. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nl"&gt;"address-form"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"projectType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"library"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"root"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"projects/address-form"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"sourceRoot"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"projects/address-form/src"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"prefix"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"lib"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"architect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"builder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"@angular-devkit/build-ng-packagr:build"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"tsConfig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"projects/address-form/tsconfig.lib.json"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"project"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"projects/address-form/ng-package.json"&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="nl"&gt;"configurations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"production"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
              &lt;/span&gt;&lt;span class="nl"&gt;"tsConfig"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"projects/address-form/tsconfig.lib.prod.json"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
          &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;p&gt;In &lt;code&gt;package.json&lt;/code&gt; we need to add a script to build our lib as well as update the path where we generate the form. &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="w"&gt;

    &lt;/span&gt;&lt;span class="nl"&gt;"generate:address-form"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ngx-form-generator -i https://raw.githubusercontent.com/verizonconnect/ngx-form-generator/master/demo/swagger.json -o projects/address-form/src/lib"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"build:libs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng build address-form"&lt;/span&gt;&lt;span class="w"&gt;


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

&lt;/div&gt;

&lt;p&gt;Now lets generate the form into the lib. &lt;/p&gt;

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

npm run generate:address-form


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

&lt;/div&gt;

&lt;p&gt;Now replace all of the exports in &lt;code&gt;proects/address-form/src/public-api.ts&lt;/code&gt; with: &lt;/p&gt;

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

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="o"&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;./lib/myApi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Build the lib with: &lt;/p&gt;

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

npm run build:libs


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

&lt;/div&gt;

&lt;p&gt;We can remove the old generated &lt;code&gt;myApi.ts&lt;/code&gt;&lt;/p&gt;

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

&lt;span class="nb"&gt;rm &lt;/span&gt;src/app/myApi.ts


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

&lt;/div&gt;

&lt;p&gt;Last, update the import of the form &lt;/p&gt;


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

&lt;p&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;addressModelForm&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;address-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;/p&gt;

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

&lt;/div&gt;
&lt;h2&gt;
&lt;br&gt;
  &lt;br&gt;
  &lt;br&gt;
  Conclusion&lt;br&gt;
&lt;/h2&gt;

&lt;p&gt;Generating forms will allow you to keep your validation rules in sync with the backend. Like generating proxies, this will greatly reduce integration bugs that occur by trying to manually implement backend to UI data contracts. &lt;/p&gt;

</description>
      <category>angular</category>
      <category>openapi</category>
      <category>reactiveforms</category>
      <category>swagger</category>
    </item>
    <item>
      <title>Introducing Commitiquette</title>
      <dc:creator>Martin McWhorter</dc:creator>
      <pubDate>Sat, 22 Feb 2020 08:32:03 +0000</pubDate>
      <link>https://dev.to/martinmcwhorter/introducing-commitiquette-245l</link>
      <guid>https://dev.to/martinmcwhorter/introducing-commitiquette-245l</guid>
      <description>&lt;p&gt;Commitiquette is a Commitizen plugin that uses your CommitLint configuration, allowing you to maintain a single set of rules for commit messages.&lt;/p&gt;

&lt;p&gt;Consistent commit messages that follow a convention are useful for automating generation of changelogs, automating versioning based on &lt;strong&gt;fix&lt;/strong&gt; (patch), &lt;strong&gt;feature&lt;/strong&gt; (minor) and &lt;strong&gt;breaking change&lt;/strong&gt; (major) of the commit. &lt;/p&gt;

&lt;p&gt;Conventional commits have the beneficial side-effect of causing developers to make more small commits, rather than fewer large commits, limited to the type and scope of the change. This may actually be the most important feature of conventional commit messages. &lt;/p&gt;

&lt;p&gt;Commiting code should be like voting in Chicago. Commit early and commit often. &lt;/p&gt;

&lt;p&gt;If you are already familiar with CommitLint and Commitizen, you can skip the next two sections and just configure Commitiquette. &lt;/p&gt;

&lt;h2&gt;
  
  
  Commitizen
&lt;/h2&gt;

&lt;p&gt;There are more options for installing and configuring Commitizen than we will go into here. See the &lt;a href="http://commitizen.github.io/cz-cli/"&gt;official documentation&lt;/a&gt; to learn more. &lt;/p&gt;

&lt;p&gt;To add Commitizen to your project, paste the following command in the project's root directory.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx commitizen init cz-conventional-changelog --save-dev --save-exact
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next add Husky to manage git hooks&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install husky --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally we will add the following snippet to our &lt;code&gt;packages.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"husky": {
  "hooks": {
    "prepare-commit-msg": "exec &amp;lt; /dev/tty &amp;amp;&amp;amp; git cz --hook || true",
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point Commitizen should be configured in your repository. When you commit changes with &lt;code&gt;git commit&lt;/code&gt;you will be prompted by Commitizen. &lt;/p&gt;

&lt;h2&gt;
  
  
  CommitLint
&lt;/h2&gt;

&lt;p&gt;While Commitizen is helpful in guiding contributers in creating commit messages, developers using a GUI to commit won't be prompted by can easily unwittingly bypass it. This is why it is important to lint the commit messages.&lt;/p&gt;

&lt;p&gt;CommitLint had lots of options for installation and configuration, including setup for CI. See the official &lt;a href="https://commitlint.js.org/"&gt;documentaion&lt;/a&gt; for more options. &lt;/p&gt;

&lt;p&gt;Install and configure CommitLint in your project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save-dev @commitlint/{cli,config-conventional}
echo "module.exports = {extends: ['@commitlint/config-conventional']};" &amp;gt; commitlint.config.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we will need to add another like to the husky configuration within &lt;code&gt;package.json&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"husky": {
  "hooks": {
    "prepare-commit-msg": "exec &amp;lt; /dev/tty &amp;amp;&amp;amp; git cz --hook || true",
    "commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, Commitlint should stop commits where the message fails the lint. Again, this is not bulletproof. If you require gated commits CommitLint should be configured in CI.&lt;/p&gt;

&lt;h2&gt;
  
  
  Commitiquette
&lt;/h2&gt;

&lt;p&gt;CommitLint and Commitizen should be somewhat in sync applying similar rules. Though as soon as you apply project or workspace specific rules, you will find you will need to maintain these rules twice.&lt;/p&gt;

&lt;p&gt;This is where Commitiquette comes in by using the CommitLint config for Commitizen. &lt;/p&gt;

&lt;p&gt;We will install Commitiquette&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install commitiquette --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next we update Commitizens's config to use Commitiquette. In &lt;code&gt;package.json&lt;/code&gt; find the Commitizen config added previously by &lt;code&gt;npx commitizen init...&lt;/code&gt; and update is so&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  "config": {
    "commitizen": {
      "path": "commitiquette"
    }
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can change our &lt;code&gt;commitlint.config.js&lt;/code&gt; and Commitizen will pick these changes up automatically! &lt;/p&gt;

&lt;p&gt;See the CommitLint documentation for a complete list of &lt;a href="https://commitlint.js.org/#/reference-rule"&gt;rules&lt;/a&gt; that may be applied to both CommitLint and Commitiquette. &lt;/p&gt;

&lt;p&gt;So now let's configure CommitLint to validate our scope is an item in an array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'scope-enum': [2, 'always', ['docs', 'core', 'lib', 'misc', 'etc']]
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CommitLint will now validate that the scope is one of the elements defined in the above rule. Commitizen, through the Commitiquette plugin, will prompt the contributor to select from this list for the scope of the commit.&lt;/p&gt;

&lt;p&gt;Commitiquette can help guide contributors to make smaller, focused commits that follow a shared set of rule based conventions. &lt;/p&gt;

</description>
      <category>git</category>
      <category>node</category>
      <category>commit</category>
    </item>
    <item>
      <title>Deceptive Sales Tactics at Halfords</title>
      <dc:creator>Martin McWhorter</dc:creator>
      <pubDate>Tue, 31 Dec 2019 22:29:53 +0000</pubDate>
      <link>https://dev.to/martinmcwhorter/deceptive-sales-tactics-at-halfords-3m1b</link>
      <guid>https://dev.to/martinmcwhorter/deceptive-sales-tactics-at-halfords-3m1b</guid>
      <description>&lt;p&gt;On December 16th 2019 I went into Halfords, Carrickmines, Dublin 18, to buy a bicycle for my daughter's birthday. I spoke with a sales person and explained I am only interested in the bicycle if it is in stock, as with the holidays -- I would not have faith that they would be able to order one for me to pickup on the 27th of December, the day before my daughters birthday. &lt;/p&gt;

&lt;p&gt;They checked the backroom and told me it was indeed in stock and I could take it in the box that day, or have it assembled by the staff and pick it up on the 27th. &lt;/p&gt;

&lt;p&gt;I agreed to have the in stock bike assembled, with the addition of stabilisers, and pick it up on the 27th. I was then quoted a price for the bike, assembly and stabilisers  for €192. I paid that in full on the day with a credit card. I noted to the sales person that the assembly and stabilisers were not on the receipt. He told me not to worry, that they are included in the price. &lt;/p&gt;

&lt;p&gt;On the day I was to pick up the bike I got a telephone call at 9:56 am to tell me that they did not have the bike I had purchased, that they sold it to someone else. I asked if the in store display was in good condition, as if not I could still go to another bike shop. The store employee agreed to check and ring me back. I never got a call back and spent the next four hours at work trying to ring the store, they never answered the phone that day. &lt;/p&gt;

&lt;p&gt;The next day, the 28th (my daughters birthday). I finally got through to the store to -- and then to the manager. He said he would look into it and call me back. I missed a few of his calls as we were driving in the car to my daughter's birthday party when he rang. Though I rang him back and he said they could give me a 15% discount on the damaged in store display (prominent scratch on the frame and badly discoloured white tyres) -- or that they would build a new bike the following Monday -- but would not do anything to remedy selling the bicycle I had already purchased to another customer. &lt;/p&gt;

&lt;p&gt;Then when I went to the shop to pickup the display model, they told me they would need to charge me extra for the stabilisers, even though this was included in the quoted price on the 16th of December by the sales person. &lt;/p&gt;

&lt;p&gt;In my view their are two deceptive practices here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selling a product as in stock -- then selling that stock to another customer. I would have left the shop and gone to another shop if they were honest and told me they were going to do this. I stipulated upfront I was only interested in purchasing the bike if it was in stock.&lt;/li&gt;
&lt;li&gt;Claiming the stabilisers were included at time of the sale and then changing this when I went to pick up the bike. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I left the shop without the bicycle because it was clear to me that they are engaged in deceptive practices. I felt bullied and condescended-to by the manager when I brought up these deceptive tactics.&lt;/p&gt;

&lt;p&gt;After contacting Halfords customer support and reporting the above, this is the response I received:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dear Martin, &lt;/p&gt;

&lt;p&gt;Thank you for the response. After speaking to the store and my managers here at Head Office, we have come to the conclusion that we would stick by the store with this matter.&lt;/p&gt;

&lt;p&gt;I can advise if you wish to go to the store to get your refund for the bike you can go there with the card this was paid for and I can then advise the store of this for you. The other option is that the store are advising the most they can do is the 15% off the bike as discussed in the store. &lt;/p&gt;

&lt;p&gt;I am ever so sorry about this. If you are unhappy with the outcome you can seek legal advice regarding this&lt;/p&gt;

&lt;p&gt;I hope this helps and if I can be of any further assistance, please do not hesitate to contact me via email or on 0330 135 9779. &lt;/p&gt;

&lt;p&gt;Kind regards, &lt;/p&gt;

&lt;p&gt;Niamh&lt;br&gt;
Customer Support Team&lt;/p&gt;
&lt;/blockquote&gt;

</description>
    </item>
    <item>
      <title>Recipe: Chicago Tavern Style Pizza</title>
      <dc:creator>Martin McWhorter</dc:creator>
      <pubDate>Mon, 30 Dec 2019 17:25:57 +0000</pubDate>
      <link>https://dev.to/martinmcwhorter/recipe-chicago-tavern-style-pizza-4dkb</link>
      <guid>https://dev.to/martinmcwhorter/recipe-chicago-tavern-style-pizza-4dkb</guid>
      <description>&lt;p&gt;Though Chicago may be known for its stuffed, deep dish and thick crust pizzas, a vast majority of the pizzas sold and consumed are thin crust, what is known in the trade as Tavern-Style Pizza. The stuffed and deep dish being a relatively recent invention from the early 1970s and 1940s respectively. Thin tavern style dates back to Vito and Nick's Tavern opened and operated by Sicilian immigrants in the 1920s. Thick crust is the second oldest Chicago pizza tradition based off of Sicilian pan pizza as well. &lt;/p&gt;

&lt;p&gt;I spent my teenage years working in a Barnaby's Pizza in the suburbs of Chicago and ran the pizza kitchen 6 nights a week. The oven had 6 rotating shelves that held 6 large pizzas each. I didn't think I would ever make pizza again when I left Barnaby's. &lt;/p&gt;

&lt;p&gt;When I moved to Ireland I was able to find good Neapolitan style pizza. There is even a Rays Original New York pizza in Dublin -- as well as Broadway Pizza Parlour if you are the the mood for New York style pizza. &lt;/p&gt;

&lt;p&gt;As far as Chicago style here in Ireland, there are no options but to make it myself. There is one place that offers what they call Chicago style, but it is just an Irish pizza with chicken and corn -- the farthest thing from Chicago style. Chicken and corn don't belong on a pizza. &lt;/p&gt;

&lt;p&gt;So here is my recipe based on a copycat Home Run Inn dough recipe that is now blocked in Europe, Barnaby's, Fassano's, and of course JB Alberto's -- the best pizza in the world. &lt;/p&gt;

&lt;h2&gt;
  
  
  Dough
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Since dough has a long fermentation period it is impractical to make dough for 1 pizza. The dough recipe will make 3 pizzas, where unless noted the rest of the recipes following is for 1 pizza.&lt;/p&gt;

&lt;p&gt;After fermentation you can evenly split the dough into three dough balls and freeze the remaining for later use. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;1 cup warm water&lt;/li&gt;
&lt;li&gt;4 cups of plain flour&lt;/li&gt;
&lt;li&gt;2 tsp salt&lt;/li&gt;
&lt;li&gt;2 tsp or 10 grams of active dry yeast or 14 grams of instant dry yeast or 30 grams of fresh yeast&lt;/li&gt;
&lt;li&gt;2/3 cup of corn oil&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Directions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Dissolve the salt in the warm water. Add the yeast, mix well, and allow to activate for 5 minutes. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you are using a Thermomix or a bread machine, you can just add the remaining ingredients and allow the machine to knead the dough for 2-5 minutes. &lt;/p&gt;

&lt;p&gt;For the manual method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add 1 cup of flour and mix well. &lt;/li&gt;
&lt;li&gt;Add 2/3 cup oil and 1 and 1/2 cup flour and mix well. &lt;/li&gt;
&lt;li&gt;Add remaining 1 and 1/2 cup flour and mix well. &lt;/li&gt;
&lt;li&gt;Knead the dough for five minutes. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Place the dough in a large bowl and cover the dough with a dampened cloth and allow to ferment in a warm place. It may be helpful to place the dough in a proving box or in the oven with the oven light on, or set to 50°C with oven door open, for an hour to help start the fermentation process. &lt;/p&gt;

&lt;p&gt;After an hour or two punch down the dough. &lt;/p&gt;

&lt;p&gt;Allow the dough to ferment at, or a little above, room temperature for 24 hours. Place the dough in the refrigerator and allow to ferment for an additional 24-48 hours for a total of 48 to 72 hours.   &lt;/p&gt;

&lt;h2&gt;
  
  
  Sauce
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;700g passata should give you enough sauce for 3 pizzas. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;500 - 700g Passata &lt;/li&gt;
&lt;li&gt;140g Tomato Puree &lt;/li&gt;
&lt;li&gt;1 tsp salt&lt;/li&gt;
&lt;li&gt;1/2 tsp Ground Black Pepper (do not use coarse ground -- the finer ground the better)&lt;/li&gt;
&lt;li&gt;1 tbsp Dry Basil&lt;/li&gt;
&lt;li&gt;2 tsp Dry Oregano &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The thicker or more rustic the passata the better. Passata from sweet tomatoes, rather than acidic, works better -- though avoid adding sugar. &lt;/p&gt;

&lt;h3&gt;
  
  
  Directions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pour the passata into a large bowl and mix in the tomato puree. &lt;/li&gt;
&lt;li&gt;Mix in the salt to taste, it should be a balanced.&lt;/li&gt;
&lt;li&gt;Mix in the black pepper to taste, the pepper should not overwhelm the sauce. &lt;/li&gt;
&lt;li&gt;Mix in the basil and oregano. This should give the sauce its signature taste. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Sausage
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Except for dough, sauce and cheese -- all of the other toppings are optional. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sausage on pizza is not a thing here in Ireland. Ordering sausage on a pizza and you may end up with hotdogs or breakfast sausages on your pizza. &lt;/p&gt;

&lt;p&gt;Pizza sausage is not a cased sausage, but rather the sausage filling. The key to the flavour is the fennel seeds. &lt;/p&gt;

&lt;p&gt;In Chicago it is the most popular topping, where pepperoni or salami would be the most popular the rest of the world over, which may trace back to Chicago once being the "hog butcher to the world" with the industrial pig slaughterhouse and now infamous stockyards at the end of the 19th century. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;100g minced pork (should be between a ping-pong and billard ball in size). You can ball and freeze the remaining pork -- or make more sausage. &lt;/li&gt;
&lt;li&gt;2 tsp Salt&lt;/li&gt;
&lt;li&gt;2 tsp Ground Black Pepper (fine ground)&lt;/li&gt;
&lt;li&gt;2 tsp Smoked Peperica&lt;/li&gt;
&lt;li&gt;2 tsp Dry Basil&lt;/li&gt;
&lt;li&gt;1 tbsp Fennel Seeds&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Directions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Flatten the minced pork onto a plate.&lt;/li&gt;
&lt;li&gt;Spread the ingredients over the pork.&lt;/li&gt;
&lt;li&gt;Mix the sausage well by folding it into itself, then form back into a ball. &lt;/li&gt;
&lt;li&gt;This can be refrigerated until needed. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Onion
&lt;/h2&gt;

&lt;p&gt;Peel and hand dice one white onion into 1 cm cubes. &lt;/p&gt;

&lt;h2&gt;
  
  
  Mushroom
&lt;/h2&gt;

&lt;p&gt;Wash and thinly slice 2-3 medium white mushrooms. &lt;/p&gt;

&lt;h2&gt;
  
  
  Green Pepper
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Wash and cut inwards on the stem side of the pepper to remove the seeds. Remove any connecting tissue and wash the inside of the pepper.
&lt;/li&gt;
&lt;li&gt;Thinly slice rings, .5 to 1cm thick, from the open side of the pepper. &lt;/li&gt;
&lt;li&gt;Then slice these rings in half. &lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; 1 green bell pepper is enough for two pizzas. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Black Olive
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Soak 6-8 black olives in water for 5-20 minutes to remove salt and brine. &lt;/li&gt;
&lt;li&gt;Slice the olives as thin as possible. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Cheese
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; Use dry mozzarella blocks rather than fresh mozzarella or grated mozzarella. Fresh mozzarella has too much moisture and grated mozzarella will lack the flavor. Dunnes, here in Ireland, stocks mozzarella blocks.   &lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;Grate 200g dry mozzarella block with Thermomix, food processor or by hand. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Assembly
&lt;/h2&gt;

&lt;p&gt;Preheat your oven as hot as it goes. If you have a pizza stone place it on the bottom rack of your oven and allow it to preheat for 40 minutes. &lt;/p&gt;

&lt;h3&gt;
  
  
  Crust
&lt;/h3&gt;

&lt;p&gt;Separate the dough into three even balls.&lt;/p&gt;

&lt;p&gt;Flour your workspace and roll out the dough into a circle 15 inches in diameter. Use a 14" oven pizza tray as a template or guide. Around the pizza track you should have a half inch overlap around the pizza. It should be about 1/2 (.5) cm thick. Use a rolling pizza cutter to trim off any extra. &lt;/p&gt;

&lt;p&gt;Dust your pizza peel or a large preparation tray with corn meal (polenta) and transfer the dough and pizza tray. Crimp the edges around the pizza dough with the your thumb and forefinger.&lt;/p&gt;

&lt;p&gt;If your oven does not go to at least 250°c or 500°f, blind bake your pizza crust for 5-7 minutes on a well greased baking or pizza tray before assembling the pizza. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If your oven goes up to at least 250°c and you have a pizza stone, there is no need to blind bake. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Sauce
&lt;/h3&gt;

&lt;p&gt;Spread 5 tbsp of sauce with a ladle or large spoon over the dough all the way to the inside of the edge crimps. Be sure not to leave any gaps. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Left over sauce may be used as a pasta sauce.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Sausage
&lt;/h3&gt;

&lt;p&gt;Sausage is the first topping on the pizza. &lt;/p&gt;

&lt;p&gt;With your thumb and forefinger grab 20 cent to 50 cent balls of sausage and press down onto the pizza edge just inside the crimp, circling inward at 1-2 inch spaces. Be sure to flatten these out as any peaks sticking out from the cheese will burn.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Pepperoni (alternative to or additional to sausage)
&lt;/h3&gt;

&lt;p&gt;Pepperoni cannot be ignored as a pizza topping. &lt;/p&gt;

&lt;p&gt;The best pizza pepperoni I have found is Horgan's Brand pepperoni (made in Germany) sold in Fresh markets. The Tesco brand pizza pepperoni is also good. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pepperoni goes under the cheese between the sausage and onion, not on top of the cheese. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Place each slice around the all the way to the edge crimp, with no gap between each pepperoni and wind all the way in. &lt;/p&gt;

&lt;p&gt;1 package of Horgan's pepperoni makes 1 pizza. &lt;/p&gt;

&lt;h3&gt;
  
  
  Mushroom and Onion
&lt;/h3&gt;

&lt;p&gt;Both of these go under the cheese as well. &lt;/p&gt;

&lt;p&gt;Spread the onion, and then the mushroom, evenly over the pizza being sure to get to each edge. &lt;/p&gt;

&lt;h3&gt;
  
  
  Cheese
&lt;/h3&gt;

&lt;p&gt;Start with the outside of the pizza and spread the cheese all the way around just inside, and all the way up to, the crimp at the edge working your way to the center of the pizza. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Because outside of the pizza will cook faster than the ceter, you should imperceptibly cheese the parameter more than the center. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Green Peppers and Olives
&lt;/h3&gt;

&lt;p&gt;Spread the peppers and olives all the way to the edges of the pizza. &lt;/p&gt;

&lt;h3&gt;
  
  
  Final touches
&lt;/h3&gt;

&lt;p&gt;Sprinkle a tsp of basil and a pinch of fine ground black pepper over the pizza. &lt;/p&gt;

&lt;h3&gt;
  
  
  Bake
&lt;/h3&gt;

&lt;p&gt;Bake until the (white) cheese starts to turn from yellow to brown. &lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hM-wdsrz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1re24mdpnt8n815cb76a.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hM-wdsrz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://thepracticaldev.s3.amazonaws.com/i/1re24mdpnt8n815cb76a.jpg" alt="Perfectly Done Pizza" width="880" height="660"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Remove from oven. Place a cold oven grate onto your workspace and pass the pizza peel or a large knife (or both) under the pizza to remove as much of the polenta (corn meal) from the bottom of your pizza before cutting. &lt;/p&gt;

&lt;p&gt;Put the pizza back onto the peel and cut into squares with three parallel cuts across the pizza, then repeat with three cross parallel cuts. Use a large knife rather than a circular pizza cutter.  &lt;/p&gt;

</description>
      <category>recipe</category>
      <category>pizza</category>
      <category>chicago</category>
    </item>
    <item>
      <title>Extending Angular Material Theme System: Additional Palettes</title>
      <dc:creator>Martin McWhorter</dc:creator>
      <pubDate>Tue, 17 Dec 2019 09:57:27 +0000</pubDate>
      <link>https://dev.to/martinmcwhorter/extending-angular-material-theme-system-n50</link>
      <guid>https://dev.to/martinmcwhorter/extending-angular-material-theme-system-n50</guid>
      <description>&lt;p&gt;The Angular Material project provides a powerful theming system. This theme system provides a few palettes: Primary, Accent and Warn. It may not be obvious how to extend the theme system to provide additional palettes -- or how to then use those extended palettes. &lt;/p&gt;

&lt;p&gt;Here we will go through how to&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add palettes to a theme&lt;/li&gt;
&lt;li&gt;Use these additional palettes&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Theme System
&lt;/h2&gt;

&lt;p&gt;First we have to familiarize ourselves with how the theme system works before we can extend it.&lt;/p&gt;

&lt;p&gt;The theme is constructed as a set of SCSS maps. A map in SCSS is just an array of key-value pairs. Similar to a Map in Java, a Dictionary in C# or a Record in TypeScript.&lt;/p&gt;

&lt;p&gt;If we take a look at the &lt;a href="https://github.com/angular/components/blob/2adf6294b52088e0f4b6284672cc2ca5e9163c20/src/material/core/theming/_theming.scss#L68"&gt;source&lt;/a&gt; we can see the functions for creating a light or dark theme just return a map containing the three material palates, a foreground and background maps, and an is-dark boolean.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@function&lt;/span&gt; &lt;span class="nf"&gt;mat-light-theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$accent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$warn&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-palette&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$mat-red&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;@return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;primary&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;accent&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$accent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;warn&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$warn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;is-dark&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;false&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;foreground&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$mat-light-theme-foreground&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$mat-light-theme-background&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So we can add our &lt;code&gt;success&lt;/code&gt;palette simply by wrapping the function and adding our new bit in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@function&lt;/span&gt; &lt;span class="nf"&gt;my-light-theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$accent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$warn&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-palette&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$mat-red&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$success&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-palette&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$mat-green&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;@return&lt;/span&gt; &lt;span class="nf"&gt;map-merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mat-light-theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$accent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$warn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$success&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;We can now repeat this for the dark theme.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@function&lt;/span&gt; &lt;span class="nf"&gt;my-dark-theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$accent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$warn&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-palette&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$mat-red&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$success&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-palette&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$mat-green&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;@return&lt;/span&gt; &lt;span class="nf"&gt;map-merge&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;mat-dark-theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$accent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$warn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$success&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;In our &lt;code&gt;style.scss&lt;/code&gt; where we would include a custom theme using &lt;code&gt;mat-light-theme(..)&lt;/code&gt; or &lt;code&gt;mat-dark-theme(..)&lt;/code&gt;, we now use &lt;code&gt;my-light-theme(..)&lt;/code&gt; and &lt;code&gt;my-dark-theme(..)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;At this point we will be be able to use this theme palette in our own components. These components can now easily be re-themed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@import&lt;/span&gt; &lt;span class="s1"&gt;'~@angular/material/theming'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;awesome-component-theme&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$theme&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;$success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;map-get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$theme&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nv"&gt;$success-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$success&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nv"&gt;$success-contrast&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;mat-color&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$success&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default-contrast&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="nc"&gt;.app-awesome&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$success-color&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;$success-contrast&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  What about Material components?
&lt;/h2&gt;

&lt;p&gt;This is well and good, we can use our new theme palette in our own components. But how can we use this in Angular Material components?&lt;/p&gt;

&lt;p&gt;Lets add this to the MatButton component. &lt;/p&gt;

&lt;p&gt;First we need to override the &lt;code&gt;_mat-button-theme-property&lt;/code&gt; mixin to add the &lt;code&gt;mat-success&lt;/code&gt; classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight scss"&gt;&lt;code&gt;&lt;span class="k"&gt;@mixin&lt;/span&gt; &lt;span class="nf"&gt;_mat-button-theme-property&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$theme&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$property&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$hue&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;$primary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;map-get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$theme&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;primary&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nv"&gt;$accent&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;map-get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$theme&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;accent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nv"&gt;$warn&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;map-get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$theme&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;warn&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nv"&gt;$success&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;map-get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$theme&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nv"&gt;$background&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;map-get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$theme&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;background&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nv"&gt;$foreground&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;map-get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$theme&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;foreground&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

  &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;.mat-primary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nv"&gt;$property&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="nd"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;mat-color&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;hue&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;.mat-accent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nv"&gt;$property&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="nd"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;mat-color&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;accent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;hue&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;.mat-warn&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nv"&gt;$property&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="nd"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;mat-color&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;warn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;hue&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;.mat-success&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nv"&gt;$property&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="nd"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;mat-color&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;success&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;hue&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;.mat-primary&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;.mat-accent&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;.mat-warn&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nc"&gt;.mat-success&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;&amp;amp;&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;disabled&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;$palette&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$property&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s1"&gt;'color'&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$foreground&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$background&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nv"&gt;$property&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="nd"&gt;:&lt;/span&gt; &lt;span class="nt"&gt;mat-color&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="nt"&gt;palette&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nt"&gt;disabled-button&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we cannot simply use:&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;button&lt;/span&gt; &lt;span class="na"&gt;mat-button&lt;/span&gt; &lt;span class="na"&gt;color=&lt;/span&gt;&lt;span class="s"&gt;"success"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;SUCCESS&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;This will work ok, until it doesn't. &lt;/p&gt;

&lt;p&gt;It only works because of regression bug in Angular that fails to type check string literals. This will be fixed in the future. This means that we can try to use the &lt;code&gt;mat-button color="success"&lt;/code&gt; to apply our new color to the Angular Material components -- but it only works because of a bug. So let's not do this. &lt;/p&gt;

&lt;h3&gt;
  
  
  Using a CSS Class
&lt;/h3&gt;

&lt;p&gt;One solution would be to simply add a class to the element:&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;button&lt;/span&gt; &lt;span class="na"&gt;mat-button&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"mat-success"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;SUCCESS&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Using a Directive to Extend Angular Material
&lt;/h3&gt;

&lt;p&gt;Or we can create a directive to do this for us.&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;type&lt;/span&gt; &lt;span class="nx"&gt;ColorClasses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mat-primary&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mat-accent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mat-warn&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;mat-success&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Directive&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;[myColor]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;MyColorDirective&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="kd"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;myColor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ColorClasses&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;renderer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addClass&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;element&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nativeElement&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;`mat-&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;constructor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ElementRef&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;renderer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Renderer2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-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;mat-button&lt;/span&gt; &lt;span class="na"&gt;myColor=&lt;/span&gt;&lt;span class="s"&gt;"success"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;SUCCESS&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;When the regression bug that is preventing string literals from being type checked in templates is fixed, this approach will improve developer experience. &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Angular Material is powerful, though it may seem too prescriptive at times. That is until you look into the internals of the SCSS themes, typography and see there are many extension points.&lt;/p&gt;

&lt;p&gt;One of the strengths of Angular is being able to extend using attribute directives. Adding behaviours and palettes using directives is simply the least obtrusive method for extension.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>angularmaterial</category>
      <category>theming</category>
      <category>scss</category>
    </item>
    <item>
      <title>Throttling Events in Angular with Rxjs</title>
      <dc:creator>Martin McWhorter</dc:creator>
      <pubDate>Wed, 14 Dec 2016 12:03:00 +0000</pubDate>
      <link>https://dev.to/martinmcwhorter/throttling-events-in-angular-with-rxjs-105c</link>
      <guid>https://dev.to/martinmcwhorter/throttling-events-in-angular-with-rxjs-105c</guid>
      <description>&lt;p&gt;Both Angular and Rxjs give you the ability to easily listen to events. Using Angualr's @HostListener() annotation allows a declarative binding while using Rxjs event binding allows for filtering, debouncing and throttling of events, to name a few.&lt;/p&gt;

&lt;p&gt;The prefered way to bind to events in an Angular component is to use the &lt;code&gt;@HostListener()&lt;/code&gt; annotation. This provides a clean declarative binding from an event to a method, and best of all works without the need to access any browser specific APIs such as &lt;code&gt;document&lt;/code&gt; or &lt;code&gt;window&lt;/code&gt;. Avoiding direct browser DOM APIs becomes important if you want to use the Universal server-side rendering or run the applicaton in a WebWorker. Keeping your code open to either of these possibilities, even if you have no plan at the moment, allows you to take advantage of future optimizations.&lt;/p&gt;

&lt;h3&gt;
  
  
  Throttling Resize
&lt;/h3&gt;

&lt;p&gt;You may ask, &lt;em&gt;why do I need to listen to resize events?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You may not need to. As many of your UI elements as possible should respond to form factor changes through CSS cues rather than scripted cues. Mobile and Tablet devices don't have any real stories where the viewport changes sizes that aren't handled by the &lt;code&gt;deviceorientation&lt;/code&gt; event. Their are probably some edge cases like split screen and some virtual keyboards pushing up on the browser window.&lt;/p&gt;

&lt;p&gt;Their may be some exceptions to this where you will need to script the responsiveness. For example, you may have a menu that is pinned open on desktop form factor, pinned in a minimized mode on tablets in landscape mode, and hidden behind a hamburger menu on portrait tablets and phones.&lt;/p&gt;

&lt;p&gt;Even with this scenario a valid situation where a user is resizing, not rotating, the browser window is at best an edge case.&lt;/p&gt;

&lt;p&gt;In reality the use case is a developer story. As a developer you want to be sure that your UI behaves at every width between the smallest acceptable width to the largest. You want to be able to stretch your responsive browser developer tools from tiny to extra-large and ensure that the app will display correctly for every pixel width.&lt;/p&gt;

&lt;p&gt;With Rxjs we can accomplish very simply:&lt;/p&gt;
&lt;span&gt;
&lt;/span&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;resizeObservable&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Observable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fromEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;resize&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;throttleTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nice and clean. But there is a problem with this. We are accessing the DOM &lt;code&gt;window&lt;/code&gt; directly. We could wrap this in a try/catch, or inject a &lt;em&gt;window&lt;/em&gt; into our component that gets replaced with a fake if we run on the server, but then if we decide to run in a WebWorker we are out of luck and will need to replace this code.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;p&gt;We can use the Rjxs throttle method in conjunction with Angular's &lt;code&gt;@HostLister()&lt;/code&gt; decorator annotations.&lt;/p&gt;

&lt;p&gt;In our example below we create a &lt;em&gt;Subject&lt;/em&gt; of type &lt;em&gt;number&lt;/em&gt; named &lt;code&gt;resizeSubject&lt;/code&gt;. We will call the &lt;code&gt;next()&lt;/code&gt; method on &lt;code&gt;resizeSubject&lt;/code&gt; in our event handler.&lt;/p&gt;

&lt;p&gt;We create an &lt;em&gt;Observable&lt;/em&gt; from our &lt;em&gt;Subject&lt;/em&gt; and throttle it for 200 miliseconds. Then within our &lt;code&gt;ngOnInit()&lt;/code&gt; we will &lt;em&gt;subscribe&lt;/em&gt; to our throttled observable.&lt;/p&gt;
&lt;span&gt;app.component.ts
&lt;/span&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;AppComponent&lt;/span&gt; &lt;span class="k"&gt;implements&lt;/span&gt; &lt;span class="nx"&gt;OnInit&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;resizeSubject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Subject&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;resizeObservable&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;resizeSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;asObservable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;throttleTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;HostListener&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;window:resize&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$event.target.innerWidth&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; 
  &lt;span class="nx"&gt;onResize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="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;resizeSubject&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt; 

  &lt;span class="nx"&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;resizeObservable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;subscribe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;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;doSomethingWithThrottledEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt; 

  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;doSomethingWithThrottledEvent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="c1"&gt;// . . . &lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>angular</category>
      <category>rxjs</category>
    </item>
    <item>
      <title>AngularJS 1.x with TypeScript (or ES6) Best Practices</title>
      <dc:creator>Martin McWhorter</dc:creator>
      <pubDate>Tue, 01 Mar 2016 11:37:00 +0000</pubDate>
      <link>https://dev.to/martinmcwhorter/angularjs-1-x-with-typescript-or-es6-best-practices-b9a</link>
      <guid>https://dev.to/martinmcwhorter/angularjs-1-x-with-typescript-or-es6-best-practices-b9a</guid>
      <description>&lt;p&gt;After working with AngularJS with TypeScript for the last couple of years there are a few best practices that seem to be missing from most tutorials.&lt;/p&gt;

&lt;p&gt;These practices apply whether you are developing in plain old JavaScript (ES5), ES6 (ES2015) or TypeScript.&lt;/p&gt;

&lt;p&gt;Code should never be future proofed, instead it should be extendable. Following these practices should help you create code that will easily be upgraded to Angular2 -- as well as be more maintainable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use External Modules
&lt;/h3&gt;

&lt;p&gt;Using external modules will do two things for you.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;When bundling your application external module use will automatically order your dependencies for you.&lt;/li&gt;
&lt;li&gt;External modules will eliminate the need to use &lt;code&gt;///&amp;lt;reference path="..." /&amp;gt;&lt;/code&gt; notation. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;app.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="kr"&gt;module&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;module&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;angular-ui-router&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
  &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;angular-animate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
  &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;angular-ui-bootstrap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; 
  &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;angular-translate&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PersonComponent.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;app&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;./app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;PersonComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="c1"&gt;// . . . &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;PersonComponent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;PersonComponent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Don't Use TypeScript Internal Modules/Namespaces
&lt;/h4&gt;

&lt;p&gt;Before the common use of external modules it was commonplace to use TypeScript internal modules, now renamed namespaces.&lt;/p&gt;

&lt;p&gt;TypeScript namespaces are based on the JavaScript Internal Module pattern. This pattern came about because of the lack of module encapsulation in JavaScript. With the introduction of CommonJS and ES6 modules and module syntax, the internal module pattern should be avoided.&lt;/p&gt;

&lt;p&gt;Use external commonJS/ES6 modules instead of TypeScript namespeces.&lt;/p&gt;

&lt;h4&gt;
  
  
  Don't use IIFE (Immediatly-Invoked Function Expression)
&lt;/h4&gt;

&lt;p&gt;IIFEs are common in JavaScript development as they allow you to encapsulate your code.&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="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="c1"&gt;// encapsulated closure protected from other code &lt;/span&gt;
&lt;span class="p"&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using external modules eliminates the need for explicity wrapping your code in IIFE closures. Instead a build time task (browserify, jspm or webpack) and module system will bundle and load your code into closures.&lt;/p&gt;

&lt;p&gt;IIFEs will also cause problems exporting types from your modules.&lt;/p&gt;

&lt;h4&gt;
  
  
  Only create AngularJS Modules for a purpose
&lt;/h4&gt;

&lt;p&gt;Keep the number of AngularJS modules to the minimum needed. Have a reason for creating new AngularJS modules.&lt;/p&gt;

&lt;p&gt;Such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sharing common code among different applications&lt;/li&gt;
&lt;li&gt;Making code more testable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AngularJS modules were created because of the lack of module system in JavaScript. With ES6 module syntax and commonJS modules AngularJS internal modules are a legacy artifact of AngularJS 1.x.&lt;/p&gt;

&lt;h3&gt;
  
  
  Define Services as Classes
&lt;/h3&gt;

&lt;p&gt;Defining your services as classes, which AngularJS's DI mechinism will instantiate as singletons, will make your code cleaner, easier to read, easier to maintain and easier to test.&lt;/p&gt;

&lt;p&gt;Lastly, defining your service as a class will make your code more friendly to &lt;code&gt;static typing&lt;/code&gt; with TypeScript.&lt;/p&gt;
&lt;span&gt;userProxy.ts
&lt;/span&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;IHttpService&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;app&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;../app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;UserProxy&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;$inject&lt;/span&gt; &lt;span class="o"&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;$http&lt;/span&gt;&lt;span class="dl"&gt;'&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="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;$http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IHttpService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 

  &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserLogin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
   &lt;span class="p"&gt;}&lt;/span&gt; 

  &lt;span class="nx"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/logout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;service&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userProxy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UserProxy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;app&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;../app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;UserProxy&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;./userProxy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;LoginController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 

  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;$inject&lt;/span&gt; &lt;span class="o"&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;userProxy&lt;/span&gt;&lt;span class="dl"&gt;'&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="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;userProxy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserProxy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt; 

  &lt;span class="nl"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserLogin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt; 

  &lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserLogin&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;userProxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="c1"&gt;// handle success &lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="c1"&gt;// handle error &lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LoginController&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LoginController&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the previous example we demonstrate clean type encapsulation using imports.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We import the type &lt;code&gt;import {UserProxy} from './userProxy';&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Then we use the imported type in the constructor injector, &lt;code&gt;constructor(private userProxy: UserProxy) {}&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Finally we demonstrate use of the static typing that was imported &lt;code&gt;this.userProxy.login(model).then(&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is a much more manageable approach than using TypeScript internal modules/namespaces to access types.&lt;/p&gt;

&lt;h4&gt;
  
  
  Only use the Factory Method when Needed
&lt;/h4&gt;

&lt;p&gt;In most cases your services will be singletons. Use the &lt;code&gt;service&lt;/code&gt; method to register these with AngularJS's DI, &lt;code&gt;app.service('userProxy', UserProxy)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The obvious use case for the &lt;code&gt;factory&lt;/code&gt; method is when using the factory pattern. Let's use the previous &lt;code&gt;UserProxy&lt;/code&gt; class as an example. For this example let's assume there are more than one JSON/HTTP end points that impliment this same API. We can make this class reusable with a factory.&lt;/p&gt;

&lt;p&gt;Lets update the class to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;app&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;../app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;UserProxy&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="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;$http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IHttpService&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;basePath&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="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserLogin&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&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;basePath&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/login&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt; 

  &lt;span class="nx"&gt;logout&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;post&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;basePath&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/logout&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{});&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can now use a factory to create instances of this class:&lt;/p&gt;

&lt;p&gt;userProxyFactory.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;IHttpService&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&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;app&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;../app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;UserProxy&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;./userProxy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="nx"&gt;UserProxy&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;type&lt;/span&gt; &lt;span class="nx"&gt;userProxyFactory&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;basePath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;UserProxy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="nx"&gt;userProxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$inject&lt;/span&gt; &lt;span class="o"&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;$http&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt; 
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nx"&gt;userProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$http&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;IHttpService&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="nx"&gt;userProxyFactory&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;basePath&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;UserProxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;$http&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;basePath&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;userProxy&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;userProxy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This can then be used in the controller as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;app&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;../app&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;userProxyFactory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;UserProxy&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;./userProxyFactory&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;LoginController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;userProxy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserProxy&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;$inject&lt;/span&gt; &lt;span class="o"&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;userProxy&lt;/span&gt;&lt;span class="dl"&gt;'&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;userProxyFactory&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userProxyFactory&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;userProxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;userProxyFactory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api1&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="nl"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserLogin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{};&lt;/span&gt; 

  &lt;span class="nx"&gt;submit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;UserLogin&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;userProxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;login&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;model&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="c1"&gt;// handle success &lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt; 
      &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="c1"&gt;// handle error &lt;/span&gt;
      &lt;span class="p"&gt;});&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;controller&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;LoginController&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;LoginController&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Bind Directly to Controller Properties and Methods
&lt;/h3&gt;

&lt;p&gt;Many examples still bind methods and properties to the injected &lt;code&gt;$scope&lt;/code&gt; within the controller.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// DON'T DO THIS &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;PersonController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 

  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;$inject&lt;/span&gt; &lt;span class="o"&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;$scope&lt;/span&gt;&lt;span class="dl"&gt;'&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="k"&gt;private&lt;/span&gt; &lt;span class="nx"&gt;$scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;ng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;IScope&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 

    &lt;span class="nx"&gt;$scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Person's Name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 

    &lt;span class="nx"&gt;$scope&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;save&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
      &lt;span class="c1"&gt;// . . . &lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; 
  &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is a bad practice for a few reasons.&lt;/p&gt;

&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;This has a memory impact. Every instance of this controller will have its own copy of each method bound to the scope. If the methods were instead defined as instance methods the implementation will be shared across instances. &lt;/li&gt;
&lt;li&gt;The API for this class is not exported and usable in unit tests.&lt;/li&gt;
&lt;li&gt;With larger nested applications you will run into scope inheritance collisions. These collisions will cause strange behaviour that can seem to defy reason. They are often hard to track down. &lt;/li&gt;
&lt;li&gt;It becomes easier to pass a value by reference when you include the properties parent object in the expression, &lt;code&gt;person.name&lt;/code&gt; rather than &lt;code&gt;name&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;

&lt;p&gt;Instead define the above controller like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;PersonController&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
  &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Person's Name&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;save&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="c1"&gt;// . . . &lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;code&gt;ng-router&lt;/code&gt; and &lt;code&gt;ui-router&lt;/code&gt; you will just need to name your instance of the controller with the &lt;code&gt;controllerAs&lt;/code&gt; configuration property.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use TypeScript for Unit Tests
&lt;/h3&gt;

&lt;p&gt;One of the main advantages of using TypeScript are the type annotations for the classes you want to test. Fear of breaking tests should not prevent you from refactoring rotting code. Using types with your tests will help keep your tests clean and readable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Summation
&lt;/h3&gt;

&lt;p&gt;TypeScript can be a great tool to keep your code base and easier to refactor. Your services will have solid APIs that your controllers and components will consume. Bugs will be found at compile time rather than in QA or Production.&lt;/p&gt;

&lt;p&gt;Even without the TypeScript, many of these practices can be applied to both ES6 and ES5. In ES5 you will just need to use commonJS &lt;code&gt;require&lt;/code&gt; syntax instead of the ES6 &lt;code&gt;import&lt;/code&gt; systax -- and the JavaScript Prototype Pattern instead of the &lt;code&gt;class&lt;/code&gt; keyword.&lt;/p&gt;

&lt;p&gt;Just a couple final thoughts:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Use a build system -- gulp or grunt.&lt;/li&gt;
&lt;li&gt;Use NPM -- don't use bower. You only need one JavaScript package manager system. Bower is redundant.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

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