<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Glen Smith</title>
  
  <subtitle>Java, XML and all that Jazz..</subtitle>
  <link href="http://blogs.bytecode.com.au/glen/feed/rss2.xml" rel="self"/>
  
  <link href="http://blogs.bytecode.com.au/glen/"/>
  <updated>2022-12-28T05:51:04.602Z</updated>
  <id>http://blogs.bytecode.com.au/glen/</id>
  
  <author>
    <name>Glen Smith</name>
    
  </author>
  
  <generator uri="https://hexo.io/">Hexo</generator>
  
  <entry>
    <title>2022 In Review (by the numbers)</title>
    <link href="http://blogs.bytecode.com.au/glen/2022/12/27/2022-in-review.html"/>
    <id>http://blogs.bytecode.com.au/glen/2022/12/27/2022-in-review.html</id>
    <published>2022-12-27T20:12:40.000Z</published>
    <updated>2022-12-28T05:51:04.602Z</updated>
    
    <content type="html"><![CDATA[<p>Don’t look now.. but I’m blogging!</p><p>I’ve been reflecting on a very diverse professional year. This year I’ve written or sustained codebases in the following platforms:</p><ul><li><a href="https://micronaut.io/">Micronaut</a> with <a href="https://angular.io/">Angular</a></li><li><a href="https://go.dev/">Golang</a> with <a href="https://github.com/gin-gonic/gin">Gin</a></li><li><a href="https://vuejs.org/">Vue.js</a> with <a href="https://quasar.dev/">Quasar</a></li><li><a href="https://flutter.dev/">Flutter</a> for Android &amp; iOS targets using <a href="https://mobx.netlify.app/">MobX</a></li><li><a href="https://www.gnu.org/software/bash/">Bash</a></li><li>and even large Classic Java EE codebase running on <a href="https://www.wildfly.org/">Wildfly</a></li></ul><p>It’s a struggle to remember how to define a function these days!</p><h2 id="Crunching-the-stats"><a href="#Crunching-the-stats" class="headerlink" title="Crunching the stats"></a>Crunching the stats</h2><p>I’ve been using a tiny git stats bash script discussed <a href="https://stackoverflow.com/questions/42715785/how-do-i-show-statistics-for-authors-contributions-in-git">here</a> to pull my numbers. Not large, but they do represent a decent amount of work (and a lot of learning).</p><table><thead><tr><th>Language</th><th>Commits</th><th>Files</th><th>Insertions</th><th>Deletions</th><th>Total Lines</th></tr></thead><tbody><tr><td>Java</td><td>58</td><td>70</td><td>3224</td><td>316</td><td>3540</td></tr><tr><td>Dart</td><td>133</td><td>35</td><td>4388</td><td>2068</td><td>6456</td></tr><tr><td>Go</td><td>111</td><td>145</td><td>11228</td><td>1578</td><td>12806</td></tr><tr><td>Bash</td><td>58</td><td>34</td><td>1777</td><td>282</td><td>2059</td></tr><tr><td>Totals</td><td>360</td><td>284</td><td>20617</td><td>4244</td><td>24861</td></tr></tbody></table><h2 id="Some-surprises-from-the-year"><a href="#Some-surprises-from-the-year" class="headerlink" title="Some surprises from the year"></a>Some surprises from the year</h2><p>And I’ve learned a few things along with the way…</p><ul><li><p><strong>Micronaut is a delight</strong>. It’s all the things I love about Grails, but in Java form. It’s really straightforward to get things done. I’m yet to get stuck into <a href="https://www.graalvm.org/">GraalVM</a> (on my list for first up next year). </p></li><li><p><strong>Go is verbose but relaxing</strong>. Yes, there’s lots of boiler-plate. And yes there are a few interesting design decisions, but overall I found it a really productive language and very easy to come back and maintain. <a href="https://github.com/gin-gonic/gin">Gin</a> is a fab web framework with all the built-ins (including <a href="https://github.com/swaggo/gin-swagger">Swagger</a> support). And compiling a single binary for the client’s numerous target platforms (including low memory embedded) has been something else… </p></li><li><p><strong>Flutter really does work cross platform</strong>. No, for reals. I built and tested on Android, and the client recompiled that codebase for their iPad and iPhone and everything “just worked”. Really. I was floored. Even the camera stuff worked! And the language is very Java-esque too. Super great stuff. Need to do more next year on mobile. </p></li><li><p><strong>Shell is awesome for client hacking</strong>. The scripts I developed were around letting a client hack their existing systems into talking with a third-party backend. They were slow, but super functional, and they let the client adapt them to other inhouse systems that I didn’t have access to. Super fun. </p></li><li><p><strong>Angular is awesome. Vue.js is awesome. Pick your awesome</strong>. Both super productive frameworks with great docs and examples. Great UI framework support via <a href="https://www.primefaces.org/primeng/">PrimeNG</a> or <a href="https://quasar.dev/">Quasar</a>. Produced some of the best-looking apps of my career this year. </p></li><li><p><strong>I need to code more in 2023</strong>. It brought me a lot of joy working on software this year - and it was probably less a part of my day-to-day than it has been earlier in my career. Really looking forward to leaning into it more in 2023.</p></li></ul><p>Had a blast this year with great clients and interesting work. Super grateful. </p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Don’t look now.. but I’m blogging!&lt;/p&gt;
&lt;p&gt;I’ve been reflecting on a very diverse professional year. This year I’ve written or sustained codebases in the following platforms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://micronaut.io/&quot;&gt;Micronaut&lt;/a&gt; with &lt;a href=&quot;https://angular.io/&quot;&gt;Angular&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://go.dev/&quot;&gt;Golang&lt;/a&gt; with &lt;a href=&quot;https://github.com/gin-gonic/gin&quot;&gt;Gin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vuejs.org/&quot;&gt;Vue.js&lt;/a&gt; with &lt;a href=&quot;https://quasar.dev/&quot;&gt;Quasar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://flutter.dev/&quot;&gt;Flutter&lt;/a&gt; for Android &amp;amp; iOS targets using &lt;a href=&quot;https://mobx.netlify.app/&quot;&gt;MobX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.gnu.org/software/bash/&quot;&gt;Bash&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;and even large Classic Java EE codebase running on &lt;a href=&quot;https://www.wildfly.org/&quot;&gt;Wildfly&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It’s a struggle to remember how to define a function these days!&lt;/p&gt;
&lt;h2 id=&quot;Crunching-the-stats&quot;&gt;&lt;a href=&quot;#Crunching-the-stats&quot; class=&quot;headerlink&quot; title=&quot;Crunching the stats&quot;&gt;&lt;/a&gt;Crunching the stats&lt;/h2&gt;&lt;p&gt;I’ve been using a tiny git stats bash script discussed &lt;a href=&quot;https://stackoverflow.com/questions/42715785/how-do-i-show-statistics-for-authors-contributions-in-git&quot;&gt;here&lt;/a&gt; to pull my numbers. Not large, but they do represent a decent amount of work (and a lot of learning).&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Language&lt;/th&gt;
&lt;th&gt;Commits&lt;/th&gt;
&lt;th&gt;Files&lt;/th&gt;
&lt;th&gt;Insertions&lt;/th&gt;
&lt;th&gt;Deletions&lt;/th&gt;
&lt;th&gt;Total Lines&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;td&gt;Java&lt;/td&gt;
&lt;td&gt;58&lt;/td&gt;
&lt;td&gt;70&lt;/td&gt;
&lt;td&gt;3224&lt;/td&gt;
&lt;td&gt;316&lt;/td&gt;
&lt;td&gt;3540&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dart&lt;/td&gt;
&lt;td&gt;133&lt;/td&gt;
&lt;td&gt;35&lt;/td&gt;
&lt;td&gt;4388&lt;/td&gt;
&lt;td&gt;2068&lt;/td&gt;
&lt;td&gt;6456&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Go&lt;/td&gt;
&lt;td&gt;111&lt;/td&gt;
&lt;td&gt;145&lt;/td&gt;
&lt;td&gt;11228&lt;/td&gt;
&lt;td&gt;1578&lt;/td&gt;
&lt;td&gt;12806&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bash&lt;/td&gt;
&lt;td&gt;58&lt;/td&gt;
&lt;td&gt;34&lt;/td&gt;
&lt;td&gt;1777&lt;/td&gt;
&lt;td&gt;282&lt;/td&gt;
&lt;td&gt;2059&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Totals&lt;/td&gt;
&lt;td&gt;360&lt;/td&gt;
&lt;td&gt;284&lt;/td&gt;
&lt;td&gt;20617&lt;/td&gt;
&lt;td&gt;4244&lt;/td&gt;
&lt;td&gt;24861&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;h2 id=&quot;Some-surprises-from-the-year&quot;&gt;&lt;a href=&quot;#Some-surprises-from-the-year&quot; class=&quot;headerlink&quot; title=&quot;Some surprises from the year&quot;&gt;&lt;/a&gt;Some surprises from the year&lt;/h2&gt;&lt;p&gt;And I’ve learned a few things along with the way…&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Micronaut is a delight&lt;/strong&gt;. It’s all the things I love about Grails, but in Java form. It’s really straightforward to get things done. I’m yet to get stuck into &lt;a href=&quot;https://www.graalvm.org/&quot;&gt;GraalVM&lt;/a&gt; (on my list for first up next year). &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Go is verbose but relaxing&lt;/strong&gt;. Yes, there’s lots of boiler-plate. And yes there are a few interesting design decisions, but overall I found it a really productive language and very easy to come back and maintain. &lt;a href=&quot;https://github.com/gin-gonic/gin&quot;&gt;Gin&lt;/a&gt; is a fab web framework with all the built-ins (including &lt;a href=&quot;https://github.com/swaggo/gin-swagger&quot;&gt;Swagger&lt;/a&gt; support). And compiling a single binary for the client’s numerous target platforms (including low memory embedded) has been something else… &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Flutter really does work cross platform&lt;/strong&gt;. No, for reals. I built and tested on Android, and the client recompiled that codebase for their iPad and iPhone and everything “just worked”. Really. I was floored. Even the camera stuff worked! And the language is very Java-esque too. Super great stuff. Need to do more next year on mobile. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Shell is awesome for client hacking&lt;/strong&gt;. The scripts I developed were around letting a client hack their existing systems into talking with a third-party backend. They were slow, but super functional, and they let the client adapt them to other inhouse systems that I didn’t have access to. Super fun. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Angular is awesome. Vue.js is awesome. Pick your awesome&lt;/strong&gt;. Both super productive frameworks with great docs and examples. Great UI framework support via &lt;a href=&quot;https://www.primefaces.org/primeng/&quot;&gt;PrimeNG&lt;/a&gt; or &lt;a href=&quot;https://quasar.dev/&quot;&gt;Quasar&lt;/a&gt;. Produced some of the best-looking apps of my career this year. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;I need to code more in 2023&lt;/strong&gt;. It brought me a lot of joy working on software this year - and it was probably less a part of my day-to-day than it has been earlier in my career. Really looking forward to leaning into it more in 2023.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="Flutter" scheme="http://blogs.bytecode.com.au/glen/tags/Flutter/"/>
    
    <category term="Go" scheme="http://blogs.bytecode.com.au/glen/tags/Go/"/>
    
  </entry>
  
  <entry>
    <title>Android Auto Dropping Out on a Sony unit? I can fix that for you</title>
    <link href="http://blogs.bytecode.com.au/glen/2020/03/03/fixing-sony-android-auto-dropouts-XAV-AX5000.html"/>
    <id>http://blogs.bytecode.com.au/glen/2020/03/03/fixing-sony-android-auto-dropouts-XAV-AX5000.html</id>
    <published>2020-03-03T21:07:33.000Z</published>
    <updated>2022-12-28T05:51:04.602Z</updated>
    
    <content type="html"><![CDATA[<p>I’ve just had a <a href="https://www.sony.com.au/electronics/in-car-receivers-players/xav-ax5000">Sony XAV-5000 Head Unit</a> installed into my teenagers 2006 Toyota Camry and it’s totally amazing!</p><p>The integration works great with steering controls, and whole Android Auto experience is fantastic.</p><p>However, it wasn’t always so. </p><p>If you’ve had the issue with:</p><ul><li>Frequent drops and reconnects on your Android phone</li><li>Not even recognising your phone is connected</li></ul><p>… well you’re not alone. I had the same problems.</p><p>There’s tons of threads about how bad the experience has been for people. The primary reason for the bad reviews is not the unit itself - it’s the constant dropouts. It makes the unit unusable.</p><p>But there is good news in this <a href="https://us.community.sony.com/s/question/0D50B00004Ros7CSAR/having-issues-with-my-xavax5000-randomly-dropping-android-auto-connection-and-at-times-will-tell-me-my-phone-is-not-compatible-which-it-is-i-am-using-a-samsung-galaxy-s7-edge?language=en_US">thread</a> which captures the solution towards the end of the thread:</p><pre><code>TL;DR: Replacing the USB socket with one that has a *much* shorter cable appears to have resolved the issue for me.</code></pre><p>But I have even better news. This worked for me by just using a new shorter, high-quality usb cable and attaching to the USB extension provided with the unit. I didn’t need to open the dash again - just buy a new shorter cable!</p><p>I went down to my local Officeworks and bought one of <a href="https://www.officeworks.com.au/shop/officeworks/p/comsol-flexi-usb-a-to-usb-c-cable-25cm-black-cocmsb25bk">these 25cm cables</a>:</p><p><img src="/glen/glen/images/2020/comsol-usb-cable.jpg" alt="Comsol Flexi USB-A to USB-C Cable 25cm Black"></p><p>Completely eliminated all dropouts and the unit is working perfectly. I’m connected to a Moto G7 Plus via USB-C, but the cables are also available in MicroUSB and Lightening. I’ve tried the MicroUSB on my son’s OPPO AX7 and, after we fixed the “Unrecognised USB device” error - which was related to how his Phone’s USB port was set to Midi rather than File Transfer) it works great too!</p><p>Phew! Hope it works out great for you! Once the drop-outs go away, this really is a fantastic unit. You’re going to love it. </p>]]></content>
    
    
    <summary type="html">&lt;p&gt;I’ve just had a &lt;a href=&quot;https://www.sony.com.au/electronics/in-car-receivers-players/xav-ax5000&quot;&gt;Sony XAV-5000 Head Unit&lt;/a&gt; installed into my teenagers 2006 Toyota Camry and it’s totally amazing!&lt;/p&gt;
&lt;p&gt;The integration works great with steering controls, and whole Android Auto experience is fantastic.&lt;/p&gt;
&lt;p&gt;However, it wasn’t always so. &lt;/p&gt;
&lt;p&gt;If you’ve had the issue with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Frequent drops and reconnects on your Android phone&lt;/li&gt;
&lt;li&gt;Not even recognising your phone is connected&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;… well you’re not alone. I had the same problems.&lt;/p&gt;
&lt;p&gt;There’s tons of threads about how bad the experience has been for people. The primary reason for the bad reviews is not the unit itself - it’s the constant dropouts. It makes the unit unusable.&lt;/p&gt;
&lt;p&gt;But there is good news in this &lt;a href=&quot;https://us.community.sony.com/s/question/0D50B00004Ros7CSAR/having-issues-with-my-xavax5000-randomly-dropping-android-auto-connection-and-at-times-will-tell-me-my-phone-is-not-compatible-which-it-is-i-am-using-a-samsung-galaxy-s7-edge?language=en_US&quot;&gt;thread&lt;/a&gt; which captures the solution towards the end of the thread:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;TL;DR: Replacing the USB socket with one that has a *much* shorter cable appears to have resolved the issue for me.
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But I have even better news. This worked for me by just using a new shorter, high-quality usb cable and attaching to the USB extension provided with the unit. I didn’t need to open the dash again - just buy a new shorter cable!&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>Keeping a Developer Journal</title>
    <link href="http://blogs.bytecode.com.au/glen/2019/05/30/keeping-a-developer-journal.html"/>
    <id>http://blogs.bytecode.com.au/glen/2019/05/30/keeping-a-developer-journal.html</id>
    <published>2019-05-30T23:04:56.000Z</published>
    <updated>2022-12-28T05:51:04.602Z</updated>
    
    <content type="html"><![CDATA[<p>Well it’s been a long year since I’ve posted anything here.. but it’s not because I haven’t been writing. Between studying at Uni, and keeping a chatty (and super helpful) personal journal, I’ve written more words in the last year than any other time in my life.</p><p>But it’s just that I haven’t been writing <em>publicly</em>. And I feel like I want to do more of that in this season.</p><p>So here we are.</p><p>And let me start by talking about some of my <em>private</em> writing…</p><p><img src="/glen/glen/images/2019/keeping-a-developer-journal.jpg" alt="Keeping A Developer Journal"></p><p>For the course of this year, each workday I’ve kept a “Developer Journal”. It’s really just a scrapbook of the things that I have worked on each day. </p><p>Sometimes it’s documenting weird Angular stuff, or something I’ve learned about <a href="https://www.primefaces.org/primeng/">PrimeNG</a>. It can be something I learned about refactoring or something I’ve read or realised in leveling up my professional skillset. </p><p>But often it’s simply documenting how I solved some problem that I ran into (with links to interesting stuff I discovered when I was researching it). Kinda like a personal blog but without the overhead. And super easy to search in later when I know the error message, but not how I solved it :-)</p><p>I use Microsoft OneNote since I can update it from client sites using OneNote online, as well as on my phone and laptop and everything just syncs nicely.</p><p>It’s been tremendously helpful to me - like a personal knowledgebase. I remember having friends who’ve kept personal Wikis back in the day - this is my modern version of that. But it’s also been useful to remind me of all the cool stuff I get to work on - and how much progress I’ve made on the days where I simply feel like “I’ve just got nothing done today.”</p><p>Highly recommend you take the practice for a spin for a week or two to see if it’s valuable to you. </p><p>Here’s an extract of the kind of stuff I write down. Have fun with your experiments!</p><p>(BTW.. feels great to be blogging again. Forgotten how much joy it brings me!)</p><p><img src="/glen/glen/images/2019/dev-log-extract.jpg" alt="Dev Log Extract from OneNote"></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Well it’s been a long year since I’ve posted anything here.. but it’s not because I haven’t been writing. Between studying at Uni, and keeping a chatty (and super helpful) personal journal, I’ve written more words in the last year than any other time in my life.&lt;/p&gt;
&lt;p&gt;But it’s just that I haven’t been writing &lt;em&gt;publicly&lt;/em&gt;. And I feel like I want to do more of that in this season.&lt;/p&gt;
&lt;p&gt;So here we are.&lt;/p&gt;
&lt;p&gt;And let me start by talking about some of my &lt;em&gt;private&lt;/em&gt; writing…&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2019/keeping-a-developer-journal.jpg&quot; alt=&quot;Keeping A Developer Journal&quot;&gt;&lt;/p&gt;
&lt;p&gt;For the course of this year, each workday I’ve kept a “Developer Journal”. It’s really just a scrapbook of the things that I have worked on each day. &lt;/p&gt;
&lt;p&gt;Sometimes it’s documenting weird Angular stuff, or something I’ve learned about &lt;a href=&quot;https://www.primefaces.org/primeng/&quot;&gt;PrimeNG&lt;/a&gt;. It can be something I learned about refactoring or something I’ve read or realised in leveling up my professional skillset. &lt;/p&gt;
&lt;p&gt;But often it’s simply documenting how I solved some problem that I ran into (with links to interesting stuff I discovered when I was researching it). Kinda like a personal blog but without the overhead. And super easy to search in later when I know the error message, but not how I solved it :-)&lt;/p&gt;
&lt;p&gt;I use Microsoft OneNote since I can update it from client sites using OneNote online, as well as on my phone and laptop and everything just syncs nicely.&lt;/p&gt;
&lt;p&gt;It’s been tremendously helpful to me - like a personal knowledgebase. I remember having friends who’ve kept personal Wikis back in the day - this is my modern version of that. But it’s also been useful to remind me of all the cool stuff I get to work on - and how much progress I’ve made on the days where I simply feel like “I’ve just got nothing done today.”&lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
  </entry>
  
  <entry>
    <title>Using CSSgram for Instagram Filters</title>
    <link href="http://blogs.bytecode.com.au/glen/2018/03/15/cssgram-instagram-filters.html"/>
    <id>http://blogs.bytecode.com.au/glen/2018/03/15/cssgram-instagram-filters.html</id>
    <published>2018-03-15T22:17:38.000Z</published>
    <updated>2022-12-28T05:51:04.602Z</updated>
    
    <content type="html"><![CDATA[<p>As my <a href="https://app.pluralsight.com/profile/author/glen-smith">Pluralsight PWA Sensor Course</a> leaps into record mode, I’ve been looking for ways to add visual interest to my camera shots - but without the overhead of mega-battery-drain client-side image processing.</p><p>Sounds like a great reason to dive into <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/filter">CSS filters</a> as a lightweight way to transform captured images on mobile. After a little googling, I ran into <a href="https://una.im/CSSgram/">CSSgram</a> - a CSS filters library for Instagram style filters! How cool.</p><p>Import a CSS file, and you’re ready to filter:</p><p><img src="/glen/glen/images/2018/cssgram-filters.jpg" alt="CSSgram Filters in Action"></p><p>Implementing a given filter is super quick. Pick one of the many <a href="https://github.com/una/CSSgram">style names</a>, and add it the <strong>parent</strong> element of your image, and you’re off to the races. They recommend doing that via the <code>figure</code> tag, which I’ve done in the page above with:</p><pre><code>&lt;figure class=&quot;hudson&quot;&gt;    &lt;img src=&quot;[[imageData]]&quot; on-click=&quot;selectFilter&quot;&gt;&lt;/figure&gt;&lt;figure class=&quot;inkwell&quot;&gt;    &lt;img src=&quot;[[imageData]]&quot; on-click=&quot;selectFilter&quot;&gt;&lt;/figure&gt;&lt;figure class=&quot;kelvin&quot;&gt;    &lt;img src=&quot;[[imageData]]&quot; on-click=&quot;selectFilter&quot;&gt;&lt;/figure&gt;</code></pre><p>Definitely a cool way to add some pop to your PWA image capture stuff!</p><p>Have fun!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;As my &lt;a href=&quot;https://app.pluralsight.com/profile/author/glen-smith&quot;&gt;Pluralsight PWA Sensor Course&lt;/a&gt; leaps into record mode, I’ve been looking for ways to add visual interest to my camera shots - but without the overhead of mega-battery-drain client-side image processing.&lt;/p&gt;
&lt;p&gt;Sounds like a great reason to dive into &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/filter&quot;&gt;CSS filters&lt;/a&gt; as a lightweight way to transform captured images on mobile. After a little googling, I ran into &lt;a href=&quot;https://una.im/CSSgram/&quot;&gt;CSSgram&lt;/a&gt; - a CSS filters library for Instagram style filters! How cool.&lt;/p&gt;
&lt;p&gt;Import a CSS file, and you’re ready to filter:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2018/cssgram-filters.jpg&quot; alt=&quot;CSSgram Filters in Action&quot;&gt;&lt;/p&gt;
&lt;p&gt;Implementing a given filter is super quick. Pick one of the many &lt;a href=&quot;https://github.com/una/CSSgram&quot;&gt;style names&lt;/a&gt;, and add it the &lt;strong&gt;parent&lt;/strong&gt; element of your image, and you’re off to the races. They recommend doing that via the &lt;code&gt;figure&lt;/code&gt; tag, which I’ve done in the page above with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;figure class=&amp;quot;hudson&amp;quot;&amp;gt;
    &amp;lt;img src=&amp;quot;[[imageData]]&amp;quot; on-click=&amp;quot;selectFilter&amp;quot;&amp;gt;
&amp;lt;/figure&amp;gt;

&amp;lt;figure class=&amp;quot;inkwell&amp;quot;&amp;gt;
    &amp;lt;img src=&amp;quot;[[imageData]]&amp;quot; on-click=&amp;quot;selectFilter&amp;quot;&amp;gt;
&amp;lt;/figure&amp;gt;

&amp;lt;figure class=&amp;quot;kelvin&amp;quot;&amp;gt;
    &amp;lt;img src=&amp;quot;[[imageData]]&amp;quot; on-click=&amp;quot;selectFilter&amp;quot;&amp;gt;
&amp;lt;/figure&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Definitely a cool way to add some pop to your PWA image capture stuff!&lt;/p&gt;
&lt;p&gt;Have fun!&lt;/p&gt;
</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Polymer" scheme="http://blogs.bytecode.com.au/glen/tags/Polymer/"/>
    
  </entry>
  
  <entry>
    <title>Recording Video in your PWA</title>
    <link href="http://blogs.bytecode.com.au/glen/2018/03/06/recording-pwa-video.html"/>
    <id>http://blogs.bytecode.com.au/glen/2018/03/06/recording-pwa-video.html</id>
    <published>2018-03-06T21:16:30.000Z</published>
    <updated>2022-12-28T05:51:04.602Z</updated>
    
    <content type="html"><![CDATA[<p>Whoa! I’m recording video and audio in my PWA app now! This is so crazy..</p><p>Turns out there is a <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API">MediaStream Recording API</a>, so I’m putting it to good use on my PWA Sensors course (it will appear <a href="https://app.pluralsight.com/profile/author/glen-smith">here</a> one day). </p><p>Dude! I’m actually recording a video note - with audio - in-browser on my SurfaceBook at my local Maccas McCafe!</p><p><img src="/glen/glen/images/2018/recording-video-in-pwa.jpg" alt="Recording a video in a PWA"></p><p>There’s an awesome <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API/Using_the_MediaStream_Recording_API">Mozilla post</a> that gives you a good nuts and bolts of the API - which I found super helpful.</p><p>The MediaRecorder stuff really builds on the MediaStream stuff I was talking about <a href="/glen/2018/02/28/mediadevices-specific-camera.html">last week</a>.</p><p>You take an incoming stream, then feed it into a <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder">MediaRecorder</a>. Call <code>mediaRecorder.start()</code> to start recording - in my case I supply a “ms chunk size” with <code>.start(1000)</code> so chunks of video will arrive in my callback every second. Once started, your <code>ondataavailable</code> handler will start getting chunks of video. How cool!</p><p>When you’re done recording, invoke <code>mediaRecorder.stop()</code> (which I do from a button click - not shown here). </p><p>Once you call <code>stop()</code> on the MediaRecorder to stop the recording, your <code>onstop</code> handler will get called back. You then take that nice selection of video chunks that we have accumulated in the array, and <code>Blob()</code> it into an object that we can <code>URL</code>-ize. </p><p>Finally, assign your Blob URL to a stock standard vanilla <code>&lt;video&gt;</code> component and click play to playback your video! </p><pre><code>// find my &lt;video&gt; element in the DOMconst videoPreview = this.$.videoNote;navigator.mediaDevices.getUserMedia(constraints)    .then((stream) =&gt; &#123;        let mediaRecorder = new MediaRecorder(stream);        // save for later so we can mediaRecorder.stop() from a button click        this.set(&#39;mediaRecorder&#39;, mediaRecorder);         // Start with number of ms per &quot;chunk&quot;        mediaRecorder.start(1000);                let chunks = [];                mediaRecorder.ondataavailable = function(e) &#123;                chunks.push(e.data);               &#125;        mediaRecorder.onstop = function(e) &#123;            var blob = new Blob(chunks, &#123; &#39;type&#39; : &#39;video/webm&#39; &#125;);                           videoPreview.src = URL.createObjectURL(blob);        &#125;            &#125;, (err) =&gt; &#123;        console.log(&#39;User rejected camera capture permissions&#39;, err);    &#125;);&#125;</code></pre><p>Constantly amazed at how much you can do in a browser these days.. Such an exciting time for PWAs. </p><p>Time to finish this script and get this module out the door later in the week. </p><p>Have fun!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Whoa! I’m recording video and audio in my PWA app now! This is so crazy..&lt;/p&gt;
&lt;p&gt;Turns out there is a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API&quot;&gt;MediaStream Recording API&lt;/a&gt;, so I’m putting it to good use on my PWA Sensors course (it will appear &lt;a href=&quot;https://app.pluralsight.com/profile/author/glen-smith&quot;&gt;here&lt;/a&gt; one day). &lt;/p&gt;
&lt;p&gt;Dude! I’m actually recording a video note - with audio - in-browser on my SurfaceBook at my local Maccas McCafe!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2018/recording-video-in-pwa.jpg&quot; alt=&quot;Recording a video in a PWA&quot;&gt;&lt;/p&gt;
&lt;p&gt;There’s an awesome &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API/Using_the_MediaStream_Recording_API&quot;&gt;Mozilla post&lt;/a&gt; that gives you a good nuts and bolts of the API - which I found super helpful.&lt;/p&gt;
&lt;p&gt;The MediaRecorder stuff really builds on the MediaStream stuff I was talking about &lt;a href=&quot;/glen/2018/02/28/mediadevices-specific-camera.html&quot;&gt;last week&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You take an incoming stream, then feed it into a &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder&quot;&gt;MediaRecorder&lt;/a&gt;. Call &lt;code&gt;mediaRecorder.start()&lt;/code&gt; to start recording - in my case I supply a “ms chunk size” with &lt;code&gt;.start(1000)&lt;/code&gt; so chunks of video will arrive in my callback every second. Once started, your &lt;code&gt;ondataavailable&lt;/code&gt; handler will start getting chunks of video. How cool!&lt;/p&gt;
&lt;p&gt;When you’re done recording, invoke &lt;code&gt;mediaRecorder.stop()&lt;/code&gt; (which I do from a button click - not shown here). &lt;/p&gt;
&lt;p&gt;Once you call &lt;code&gt;stop()&lt;/code&gt; on the MediaRecorder to stop the recording, your &lt;code&gt;onstop&lt;/code&gt; handler will get called back. You then take that nice selection of video chunks that we have accumulated in the array, and &lt;code&gt;Blob()&lt;/code&gt; it into an object that we can &lt;code&gt;URL&lt;/code&gt;-ize. &lt;/p&gt;
&lt;p&gt;Finally, assign your Blob URL to a stock standard vanilla &lt;code&gt;&amp;lt;video&amp;gt;&lt;/code&gt; component and click play to playback your video! &lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Polymer" scheme="http://blogs.bytecode.com.au/glen/tags/Polymer/"/>
    
  </entry>
  
  <entry>
    <title>Selecting a specific camera with the MediaDevices API</title>
    <link href="http://blogs.bytecode.com.au/glen/2018/02/28/mediadevices-specific-camera.html"/>
    <id>http://blogs.bytecode.com.au/glen/2018/02/28/mediadevices-specific-camera.html</id>
    <published>2018-02-28T05:00:01.000Z</published>
    <updated>2022-12-28T05:51:04.602Z</updated>
    
    <content type="html"><![CDATA[<p>I’m having a ball at the moment hacking around with the <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices">MediaDevices API</a> in preparation for an upcoming Pluralsight Course on PWA Sensors (it will appear <a href="https://app.pluralsight.com/profile/author/glen-smith">here</a> one day). It’s just crazy what you can do in a browser these days!</p><p>One cool trick I’ve been playing with is populating a selectbox with a list of available cameras, then letting the user select the camera that they’d like to work with. </p><p>The API has an <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices">enumerateDevices()</a> call which is handy for tracking down everything that’s available on your system. I iterate over the returned  <code>MediaDeviceInfo</code> objects since having their <code>label</code> and <code>deviceId</code> is handy for my next trick…</p><pre><code>navigator.mediaDevices.enumerateDevices()    .then(function (devices) &#123;        let cameras = [];        let microphones = [];        devices.forEach(function (device) &#123;            console.log(device.kind + &quot;: &quot; + device.label +                &quot; id = &quot; + device.deviceId);            if (device.kind === &#39;videoinput&#39;) &#123;                cameras.push(device);            &#125; else if (device.kind == &#39;audioinput&#39;) &#123;                microphones.push(device);            &#125;        &#125;);        self.set(&#39;cameraDevices&#39;, cameras);        self.set(&#39;microphoneDevices&#39;, microphones);    &#125;)    .catch(function (err) &#123;        console.log(err.name + &quot;: &quot; + err.message);    &#125;);&#125;</code></pre><p>Now I have that those list of MediaDeviceInfo, I can put them into a dropdown and we’re off to the races:</p><p><img src="/glen/glen/images/2018/capture-by-deviceid.jpg" alt="Populate a Select with DeviceIds"></p><p>But what happens if you have more than one device? My Surfacebook has a front and rear camara, and so does my mobile handset. How do you tell the API which one to use?</p><p>The magic you need is the super-handy <a href="https://developer.mozilla.org/en-US/docs/Web/API/Media_Streams_API/Constraints">Constraints</a> block. Pass this into your media acquisition, and can specify exactly which DeviceId you’d like:</p><pre><code>let constraints = &#123;    video: &#123;        deviceId: selectedCamera.deviceId    &#125;,    audio: false,&#125;;</code></pre><p>That constraints object is all the secret sauce you need. Pass those constraints in your <a href="https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia">getUserMedia</a> call and you’re in business:</p><pre><code>navigator.mediaDevices.getUserMedia(constraints).then((stream) =&gt; &#123;    photoPreview.srcObject = stream;    this.set(&#39;cameraActive&#39;, true);&#125;, (err) =&gt; &#123;    console.log(&#39;User rejected camera capture permissions&#39;, err);    this.set(&#39;captureRejected&#39;, true);&#125;);</code></pre><p>Can’t stop winning! But right now I need to get back to scripting my course - still have some media recording stuff to churn through (super, super fun!). I have a DevEditor progress call tomorrow and I’m way behind! Eeek!</p><p>Will post some more media recording coolness here soon.</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;I’m having a ball at the moment hacking around with the &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices&quot;&gt;MediaDevices API&lt;/a&gt; in preparation for an upcoming Pluralsight Course on PWA Sensors (it will appear &lt;a href=&quot;https://app.pluralsight.com/profile/author/glen-smith&quot;&gt;here&lt;/a&gt; one day). It’s just crazy what you can do in a browser these days!&lt;/p&gt;
&lt;p&gt;One cool trick I’ve been playing with is populating a selectbox with a list of available cameras, then letting the user select the camera that they’d like to work with. &lt;/p&gt;
&lt;p&gt;The API has an &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/enumerateDevices&quot;&gt;enumerateDevices()&lt;/a&gt; call which is handy for tracking down everything that’s available on your system. I iterate over the returned  &lt;code&gt;MediaDeviceInfo&lt;/code&gt; objects since having their &lt;code&gt;label&lt;/code&gt; and &lt;code&gt;deviceId&lt;/code&gt; is handy for my next trick…&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;navigator.mediaDevices.enumerateDevices()
    .then(function (devices) &amp;#123;
        let cameras = [];
        let microphones = [];
        devices.forEach(function (device) &amp;#123;
            console.log(device.kind + &amp;quot;: &amp;quot; + device.label +
                &amp;quot; id = &amp;quot; + device.deviceId);
            if (device.kind === &amp;#39;videoinput&amp;#39;) &amp;#123;
                cameras.push(device);
            &amp;#125; else if (device.kind == &amp;#39;audioinput&amp;#39;) &amp;#123;
                microphones.push(device);
            &amp;#125;
        &amp;#125;);
        self.set(&amp;#39;cameraDevices&amp;#39;, cameras);
        self.set(&amp;#39;microphoneDevices&amp;#39;, microphones);
    &amp;#125;)
    .catch(function (err) &amp;#123;
        console.log(err.name + &amp;quot;: &amp;quot; + err.message);
    &amp;#125;);
&amp;#125;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now I have that those list of MediaDeviceInfo, I can put them into a dropdown and we’re off to the races:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2018/capture-by-deviceid.jpg&quot; alt=&quot;Populate a Select with DeviceIds&quot;&gt;&lt;/p&gt;
&lt;p&gt;But what happens if you have more than one device? My Surfacebook has a front and rear camara, and so does my mobile handset. How do you tell the API which one to use?&lt;/p&gt;
&lt;p&gt;The magic you need is the super-handy &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Media_Streams_API/Constraints&quot;&gt;Constraints&lt;/a&gt; block. Pass this into your media acquisition, and can specify exactly which DeviceId you’d like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;let constraints = &amp;#123;
    video: &amp;#123;
        deviceId: selectedCamera.deviceId
    &amp;#125;,
    audio: false,
&amp;#125;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That constraints object is all the secret sauce you need. Pass those constraints in your &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/MediaDevices/getUserMedia&quot;&gt;getUserMedia&lt;/a&gt; call and you’re in business:&lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Polymer" scheme="http://blogs.bytecode.com.au/glen/tags/Polymer/"/>
    
  </entry>
  
  <entry>
    <title>Overcoming Resistance (for Pluralsight Authors)</title>
    <link href="http://blogs.bytecode.com.au/glen/2018/02/22/overcoming-pluralsight-resistance.html"/>
    <id>http://blogs.bytecode.com.au/glen/2018/02/22/overcoming-pluralsight-resistance.html</id>
    <published>2018-02-22T02:40:37.000Z</published>
    <updated>2022-12-28T05:51:04.602Z</updated>
    
    <content type="html"><![CDATA[<p>If you’ve not heard Steven Pressfield talk about The Resistance, you need to spend three minutes and <a href="https://youtu.be/RH5B2j843WU">set that right</a>.</p><p>Good. Now we’re on the same page..</p><p>I’m an avid daily journal person - I’ve been collecting daily posts for the last four years which I keep in OneNote. But this recent journal entry seems like something others may benefit from.</p><p>This post is about a bunch of my own internal resistance reasons that I use to procrastinate doing actual work on my next Pluralsight Course (which is on PWA sensors, and which I’m actually super pumped about)… and the rebutt to those lies so you can just get on with <em>Turning Pro</em> and actually doing the work.</p><p>Enjoy the journal!</p><hr><h2 id="Daily-Journal-Tuesday-20th-February-2018"><a href="#Daily-Journal-Tuesday-20th-February-2018" class="headerlink" title="Daily Journal. Tuesday, 20th February, 2018."></a>Daily Journal. Tuesday, 20th February, 2018.</h2><p>There is massive resistance on working on my Pluralsight course today - even though I have set aside the day to do just that. </p><p>So what’s under the waterline of this iceberg of resistance? What’s stopping the daily progress?</p><ul><li><p><strong>Deadlines are creating fear and disappointment.</strong> I thought my accountability stuff - asking a friend and my editor to hold me to a deadline - would help me kick my own butt and make some progress, but the reverse has happened. It’s made me freeze. Scared to progress. Terrified of clicking record. Fearful I won’t ship anything in time and miss a great opportunity. <strong>BUT:</strong> that mindset takes hold when you forget: <a href="https://jamesclear.com/goals-systems">Habits make goals come to you!!</a> Just fall in love with the daily grind and you’ll be done in no time. Just move the needle forward in some small way every day. </p></li><li><p><strong>Resentment that I’m not making hay while the sun shines.</strong> I have this awesome consulting opportunity at the moment that I could be monetizing <em>every single day</em> . But I’m busy tinkering on this slow-as-molasses course progress which I resent as anti-business-wisdom. <strong>BUT:</strong> will I resent this down the track? Absolutely not -  I know the <em>work an hour&#x2F;get paid an hour</em> thing is dead. I only do it <em>at all</em> because it’s a good way of keeping my dev skills applied in a real business team context - and grow my programming chops by working with other developers. Pluralsight scales out!</p></li><li><p><strong>Scared I don’t have the stuff.</strong> Ah, that <a href="https://en.wikipedia.org/wiki/Impostor_syndrome">old chestnut</a>. That I “don’t know this area deep enough”. The truth is that I, like everyone, have many knowledge gaps - but I’m curious, and so will explore things with a beginners mind as I go along. My mind still plays the old, “there are better people out there in this area who will rubbish and ridicule this course”.  <strong>BUT:</strong> of course, that’s all non-sense. Most real experts I know are gracious - and love to see others level up. And I’ll also be offering a ton of enthusiasm, a <a href="https://zenhabits.net/beginner/">beginner’s mind</a>, and a passion for levelling people up. </p></li><li><p><strong>Tension about having the (super large) tracts of time I (pretend I) need.</strong> I feel like there are constant interruptions, so how will I get in the flow for this course to progress? How will I move this forward in little blocks of an hour here or there? <strong>BUT:</strong> the truth of the matter is that I make great progress in a single <a href="https://en.wikipedia.org/wiki/Pomodoro_Technique">Pomodoro</a> - so there’s no risk of this lie really being true. Thinking in <a href="http://stephenguise.com/are-you-making-this-time-management-mistake/">smaller blocks of time</a> is very helpful. </p></li><li><p><strong>Zero self-compassion.</strong> No matter how much I track through, I’ll never feel like I’ve done enough, so why even start? Reality means other things <em>do</em> sometimes trump my courseware development. <strong>BUT:</strong> the <em>other</em> things that have trumped Pluralsight progress have been wonderful, and important, and it’s worth remembering my value is not measured by completed Pluralsight courses - I was created to enjoy life. Imagine if I treated myself the way that I would treat a friend who accomplished a similar amount of work in a day… I would give them a raise! So feel good about yourself, and crack on.</p></li><li><p><strong>Losing my why.</strong> I forget that I want to become a world class trainer, mentor and coach. <strong>BUT:</strong> the way that you do that is through mindful practice. I sometime resent “putting in the practice” on my Pluralsight work - since it’s not making immediate money. But then I remember that it’s not, and was never, about the money anyway!! It was about making the world a cooler place - levelling up developers in entertaining ways - and growing in my own potential - and getting better at doing online training!</p></li><li><p><strong>No next step.</strong> This one is actaully kinda true. I am a little light on the planning stage - and when you don’t have an immediate “next step” to move onto, you can spin the wheels working that out. <strong>BUT:</strong> I can grow in this area and I have great tools available to me in <a href="https://kanbanflow.com/">Kanbanflow</a> or even <a href="https://trello.com/">Trello</a> - so I’m going to develop my next steps as I go.  Certainly having no plan doesn’t serve me - so I’m going to create a coarse grain plan and refine as you go. Live the agile dream!</p></li><li><p><strong>Not making it fun.</strong> First, <a href="https://www.amazon.com/First-Learn-Practice-Tom-Heany-ebook/dp/B0085YBQEC">learn to practice</a>! <strong>BUT:</strong> the first step there is to make it fun. Give yourself little rewards. Set micro-deadlines that are actually doable - and then hit them and celebrate. No more Herculean epic tasks - those “I’m not allowed to celebrate without doing 40 hours of progress in 6 hours of work” mindsets. That’s ridiculous. And it doesn’t serve you. So leave it behind. </p></li><li><p><strong>No room for overflow.</strong> When I dive into Pluralsight, all my blogging&#x2F;vlogging&#x2F;whatever goes to zero. There’s no overflow to share. <strong>BUT:</strong> that’s crazy. I’m learning new things <em>every</em> time I sit down to work on the course, so I just need to work out a <em>lightweight</em> way to share those insights. No “massive tome” blog posts. Just punch out a few little sentences to encourage yourself. Or a quick vid to just demonstrate something cool. Or something from your journal. I’m going to commit to a Wednesday blog day.</p></li></ul><p>Well, that’s all I can think of immediately this morning. So I figured I’d just write it down so I can see the madness in some of my mindsets. </p><p>I’m going to edge forward today. I’m going to break that resistance. </p><p>Let’s get started :-)</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;If you’ve not heard Steven Pressfield talk about The Resistance, you need to spend three minutes and &lt;a href=&quot;https://youtu.be/RH5B2j843WU&quot;&gt;set that right&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Good. Now we’re on the same page..&lt;/p&gt;
&lt;p&gt;I’m an avid daily journal person - I’ve been collecting daily posts for the last four years which I keep in OneNote. But this recent journal entry seems like something others may benefit from.&lt;/p&gt;
&lt;p&gt;This post is about a bunch of my own internal resistance reasons that I use to procrastinate doing actual work on my next Pluralsight Course (which is on PWA sensors, and which I’m actually super pumped about)… and the rebutt to those lies so you can just get on with &lt;em&gt;Turning Pro&lt;/em&gt; and actually doing the work.&lt;/p&gt;
&lt;p&gt;Enjoy the journal!&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;Daily-Journal-Tuesday-20th-February-2018&quot;&gt;&lt;a href=&quot;#Daily-Journal-Tuesday-20th-February-2018&quot; class=&quot;headerlink&quot; title=&quot;Daily Journal. Tuesday, 20th February, 2018.&quot;&gt;&lt;/a&gt;Daily Journal. Tuesday, 20th February, 2018.&lt;/h2&gt;&lt;p&gt;There is massive resistance on working on my Pluralsight course today - even though I have set aside the day to do just that. &lt;/p&gt;
&lt;p&gt;So what’s under the waterline of this iceberg of resistance? What’s stopping the daily progress?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Deadlines are creating fear and disappointment.&lt;/strong&gt; I thought my accountability stuff - asking a friend and my editor to hold me to a deadline - would help me kick my own butt and make some progress, but the reverse has happened. It’s made me freeze. Scared to progress. Terrified of clicking record. Fearful I won’t ship anything in time and miss a great opportunity. &lt;strong&gt;BUT:&lt;/strong&gt; that mindset takes hold when you forget: &lt;a href=&quot;https://jamesclear.com/goals-systems&quot;&gt;Habits make goals come to you!!&lt;/a&gt; Just fall in love with the daily grind and you’ll be done in no time. Just move the needle forward in some small way every day. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Resentment that I’m not making hay while the sun shines.&lt;/strong&gt; I have this awesome consulting opportunity at the moment that I could be monetizing &lt;em&gt;every single day&lt;/em&gt; . But I’m busy tinkering on this slow-as-molasses course progress which I resent as anti-business-wisdom. &lt;strong&gt;BUT:&lt;/strong&gt; will I resent this down the track? Absolutely not -  I know the &lt;em&gt;work an hour&amp;#x2F;get paid an hour&lt;/em&gt; thing is dead. I only do it &lt;em&gt;at all&lt;/em&gt; because it’s a good way of keeping my dev skills applied in a real business team context - and grow my programming chops by working with other developers. Pluralsight scales out!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scared I don’t have the stuff.&lt;/strong&gt; Ah, that &lt;a href=&quot;https://en.wikipedia.org/wiki/Impostor_syndrome&quot;&gt;old chestnut&lt;/a&gt;. That I “don’t know this area deep enough”. The truth is that I, like everyone, have many knowledge gaps - but I’m curious, and so will explore things with a beginners mind as I go along. My mind still plays the old, “there are better people out there in this area who will rubbish and ridicule this course”.  &lt;strong&gt;BUT:&lt;/strong&gt; of course, that’s all non-sense. Most real experts I know are gracious - and love to see others level up. And I’ll also be offering a ton of enthusiasm, a &lt;a href=&quot;https://zenhabits.net/beginner/&quot;&gt;beginner’s mind&lt;/a&gt;, and a passion for levelling people up. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tension about having the (super large) tracts of time I (pretend I) need.&lt;/strong&gt; I feel like there are constant interruptions, so how will I get in the flow for this course to progress? How will I move this forward in little blocks of an hour here or there? &lt;strong&gt;BUT:&lt;/strong&gt; the truth of the matter is that I make great progress in a single &lt;a href=&quot;https://en.wikipedia.org/wiki/Pomodoro_Technique&quot;&gt;Pomodoro&lt;/a&gt; - so there’s no risk of this lie really being true. Thinking in &lt;a href=&quot;http://stephenguise.com/are-you-making-this-time-management-mistake/&quot;&gt;smaller blocks of time&lt;/a&gt; is very helpful. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Zero self-compassion.&lt;/strong&gt; No matter how much I track through, I’ll never feel like I’ve done enough, so why even start? Reality means other things &lt;em&gt;do&lt;/em&gt; sometimes trump my courseware development. &lt;strong&gt;BUT:&lt;/strong&gt; the &lt;em&gt;other&lt;/em&gt; things that have trumped Pluralsight progress have been wonderful, and important, and it’s worth remembering my value is not measured by completed Pluralsight courses - I was created to enjoy life. Imagine if I treated myself the way that I would treat a friend who accomplished a similar amount of work in a day… I would give them a raise! So feel good about yourself, and crack on.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Losing my why.&lt;/strong&gt; I forget that I want to become a world class trainer, mentor and coach. &lt;strong&gt;BUT:&lt;/strong&gt; the way that you do that is through mindful practice. I sometime resent “putting in the practice” on my Pluralsight work - since it’s not making immediate money. But then I remember that it’s not, and was never, about the money anyway!! It was about making the world a cooler place - levelling up developers in entertaining ways - and growing in my own potential - and getting better at doing online training!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No next step.&lt;/strong&gt; This one is actaully kinda true. I am a little light on the planning stage - and when you don’t have an immediate “next step” to move onto, you can spin the wheels working that out. &lt;strong&gt;BUT:&lt;/strong&gt; I can grow in this area and I have great tools available to me in &lt;a href=&quot;https://kanbanflow.com/&quot;&gt;Kanbanflow&lt;/a&gt; or even &lt;a href=&quot;https://trello.com/&quot;&gt;Trello&lt;/a&gt; - so I’m going to develop my next steps as I go.  Certainly having no plan doesn’t serve me - so I’m going to create a coarse grain plan and refine as you go. Live the agile dream!&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Not making it fun.&lt;/strong&gt; First, &lt;a href=&quot;https://www.amazon.com/First-Learn-Practice-Tom-Heany-ebook/dp/B0085YBQEC&quot;&gt;learn to practice&lt;/a&gt;! &lt;strong&gt;BUT:&lt;/strong&gt; the first step there is to make it fun. Give yourself little rewards. Set micro-deadlines that are actually doable - and then hit them and celebrate. No more Herculean epic tasks - those “I’m not allowed to celebrate without doing 40 hours of progress in 6 hours of work” mindsets. That’s ridiculous. And it doesn’t serve you. So leave it behind. &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;No room for overflow.&lt;/strong&gt; When I dive into Pluralsight, all my blogging&amp;#x2F;vlogging&amp;#x2F;whatever goes to zero. There’s no overflow to share. &lt;strong&gt;BUT:&lt;/strong&gt; that’s crazy. I’m learning new things &lt;em&gt;every&lt;/em&gt; time I sit down to work on the course, so I just need to work out a &lt;em&gt;lightweight&lt;/em&gt; way to share those insights. No “massive tome” blog posts. Just punch out a few little sentences to encourage yourself. Or a quick vid to just demonstrate something cool. Or something from your journal. I’m going to commit to a Wednesday blog day.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>Automate it. Today.</title>
    <link href="http://blogs.bytecode.com.au/glen/2018/02/14/automate-it-now.html"/>
    <id>http://blogs.bytecode.com.au/glen/2018/02/14/automate-it-now.html</id>
    <published>2018-02-14T07:57:00.000Z</published>
    <updated>2022-12-28T05:51:04.602Z</updated>
    
    <content type="html"><![CDATA[<p>These last couple of years I’ve been reflecting every day on a <a href="https://www.huffingtonpost.com/elizabeth-rider/the-scientific-reason-why_b_6392274.html">Vision Wall</a> that I keep in OneNote. It’s just a page with a bunch of images that remind me of things I’m working to build into my life.</p><p>One of the these pictures this year is around innovation.</p><p><img src="/glen/glen/images/2018/innovate.jpg" alt="Innovate It"></p><p>Innovate. That word used to conjure up “<a href="https://en.wikipedia.org/wiki/Elon_Musk">Elon Musk</a>-ish” level innovation. But no more. I now tell a different story about innovation. </p><p>My new innovation story is more about friction reduction. And automation. </p><h2 id="Removing-the-Friction"><a href="#Removing-the-Friction" class="headerlink" title="Removing the Friction"></a>Removing the Friction</h2><p>Imagine if you could remove a small percentage of the friction you experience every day delivering software. How great would that feel? Annoying tasks gone forever.</p><p>The crazy thing is that automation - using robots to do our boring work - lets us actually do that, but often we put it off since we figure we’re just doing a “one off”. Or it would be too fiddly or time consuming to automate.</p><p>Interestingly I used to work with a guy who was completely the other way around. He wouldn’t even copy a file to a floppy without creating a batch file to do it (since he figured he’d be doing it again real soon now). </p><p>I think he was onto something. </p><p>So this year I’m leaning in to “automating the friction”. That will be my innovation. If a task is annoying (and maybe even difficult and annoying), I’m going to lean into automating it. For me, and for my clients.</p><p>I will automate the fiction and boredom right out of my life (ironically, through diving deep into the difficult and boring task of automating tricky tasks)!</p><p>Cue my next Vision Wall picture.</p><p><img src="/glen/glen/images/2018/be-curious.jpg" alt="Delight in the Hard Work"></p><h2 id="Starting-with-CI-x2F-CD"><a href="#Starting-with-CI-x2F-CD" class="headerlink" title="Starting with CI&#x2F;CD"></a>Starting with CI&#x2F;CD</h2><p>A key part of my startegy is working with the resource I have. In fact, I’ve joined one of my business mates in doing the <a href="https://zenhabits.net/depth/">Depth Year</a> challenge - where I just work inside the resources I already know - but take them deeper.</p><p>I introduced <a href="https://about.gitlab.com/">GitLab</a> to my current client (via a Docker install) and it’s been working a treat. We use it for bug tracking. We use it for revision control. We even use it for basic docs. </p><p>Gitlab has tons of CI&#x2F;CD stuff in the box. You can:</p><ul><li>Hack up a YAML file; </li><li>Build your app inside a clean Docker image;</li><li>Pass in SSH keys via magic secret variables</li><li>Rsync it to staging - or a canary build</li><li>Deploy to production after QA</li><li>And tons more. Tons.</li></ul><p>But it’s all very fiddly to configure. And the docs need a polish. And it’s hard.</p><p>But since this year is about friction reduction, I dived in. And a day later I have all the cookbooks for automated build and deploy to remote hosts via rsync. It was hell, but the hell is over!</p><p>And now every time I merge to master, remote machines update and the birds sing. It’s <em>really</em> satisfying.</p><h2 id="And-onto-the-next-win"><a href="#And-onto-the-next-win" class="headerlink" title="And onto the next win.."></a>And onto the next win..</h2><p>Now I’m diving into a messy refactor so I can finally get my test harnesses working smoothly.</p><p>Reducing friction AND deliving a higher quality product to the client. </p><p>You don’t need to choose. </p><p>Except automating the hard stuff. That is definitely the choice :-)</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;These last couple of years I’ve been reflecting every day on a &lt;a href=&quot;https://www.huffingtonpost.com/elizabeth-rider/the-scientific-reason-why_b_6392274.html&quot;&gt;Vision Wall&lt;/a&gt; that I keep in OneNote. It’s just a page with a bunch of images that remind me of things I’m working to build into my life.&lt;/p&gt;
&lt;p&gt;One of the these pictures this year is around innovation.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2018/innovate.jpg&quot; alt=&quot;Innovate It&quot;&gt;&lt;/p&gt;
&lt;p&gt;Innovate. That word used to conjure up “&lt;a href=&quot;https://en.wikipedia.org/wiki/Elon_Musk&quot;&gt;Elon Musk&lt;/a&gt;-ish” level innovation. But no more. I now tell a different story about innovation. &lt;/p&gt;
&lt;p&gt;My new innovation story is more about friction reduction. And automation. &lt;/p&gt;
&lt;h2 id=&quot;Removing-the-Friction&quot;&gt;&lt;a href=&quot;#Removing-the-Friction&quot; class=&quot;headerlink&quot; title=&quot;Removing the Friction&quot;&gt;&lt;/a&gt;Removing the Friction&lt;/h2&gt;&lt;p&gt;Imagine if you could remove a small percentage of the friction you experience every day delivering software. How great would that feel? Annoying tasks gone forever.&lt;/p&gt;
&lt;p&gt;The crazy thing is that automation - using robots to do our boring work - lets us actually do that, but often we put it off since we figure we’re just doing a “one off”. Or it would be too fiddly or time consuming to automate.&lt;/p&gt;
&lt;p&gt;Interestingly I used to work with a guy who was completely the other way around. He wouldn’t even copy a file to a floppy without creating a batch file to do it (since he figured he’d be doing it again real soon now). &lt;/p&gt;
&lt;p&gt;I think he was onto something. &lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Git" scheme="http://blogs.bytecode.com.au/glen/tags/Git/"/>
    
  </entry>
  
  <entry>
    <title>Blogging into 2018</title>
    <link href="http://blogs.bytecode.com.au/glen/2018/02/08/into-2018.html"/>
    <id>http://blogs.bytecode.com.au/glen/2018/02/08/into-2018.html</id>
    <published>2018-02-08T03:36:10.000Z</published>
    <updated>2022-12-28T05:51:04.602Z</updated>
    
    <content type="html"><![CDATA[<p>Wow! We’re into 2018 already and I haven’t blogged for months and months. That’s such a shame because I’ve been doing so much cool stuff. So it’s time to get back on the horse!</p><h2 id="New-PWA-Pluralsight-Course-in-Flight"><a href="#New-PWA-Pluralsight-Course-in-Flight" class="headerlink" title="New PWA Pluralsight Course in Flight"></a>New PWA Pluralsight Course in Flight</h2><p>I’m presently working on new <a href="https://app.pluralsight.com/profile/author/glen-smith">Pluralsight Course</a> related to Progressive Web Apps and Sensor Integration. I’m still scripting but there’s tons of cool stuff in there. </p><p>It’s called Sights and Sounds</p><p><img src="/glen/glen/images/2018/sights-sounds-scratchy-logo.png" alt="Sights and Sounds Logo"></p><p>But not just any travel app. We’ll be developing a lightweight PWA on your handset and:</p><ul><li>Taking photos;</li><li>Recording videos;</li><li>Lauching Notifications;</li><li>Interacting with Fullscreen</li><li>Doing Geo &amp; directions;</li><li>Launching native apps;</li><li>Sensing network access and coping with it</li><li>Doing offline sync magic with Firebase (including image upload)</li></ul><p>I am so pumped about it. It’s pretty scratchy at the moment, but it’ll get there:</p><p><img src="/glen/glen/images/2018/sights-sounds-early-screengrab.jpg" alt="Sights and Sounds Screenshot"></p><h2 id="Discovering-Polymer"><a href="#Discovering-Polymer" class="headerlink" title="Discovering Polymer"></a>Discovering Polymer</h2><p>I’ve been doing heaps of Angular over the last year (and loving every second of it) - so my first thoughts were around teaching the PWA course with Angular.</p><p>But it’s hard to teach the concepts in Angular without it being super-Angular-specific - lots of @ViewChild action which doesn’t translate well to other frameworks.</p><p>So I stared exploring what other, more lightweight, tooling I could use to teach the course.</p><p>Then I discovered <a href="https://www.polymer-project.org/">Polymer 2</a> and fell in love!</p><p><img src="/glen/glen/images/2018/polymer-blurb.jpg" alt="Polymer Blurb"></p><p>Here’s a super, super lightweight framework - mostly just a browser API with polyfills - hence the #UseThePlatform mantra. </p><p>The kicker for me is the cool component action. I love, love, love components. And Polymer has a <a href="https://www.webcomponents.org/">vast library</a> of high quality components to get you started. So I can just throw on a <a href="https://www.webcomponents.org/element/GoogleWebComponents/google-map">Google Maps</a> component, or a bunch of <a href="https://www.webcomponents.org/collection/PolymerElements/paper-ui-elements">Material Design</a> components, wire them all up to some backing properties, and I’m productive.</p><p>The learning curve was super gentle too. It’s just JavaScript.</p><p>And the big win for teaching is the no-build-chain-just-straight-F9-driven-development. Light and fast with minimal clutter to distract you.</p><p>I’m really interested in how people find this approach from a learning perspective. And if you’re a hardcore framework person, the translation to your framework of choice should be very straightforward - or just use the existing Polymer integrations to bolt in WebComponents to your existing Angular&#x2F;React&#x2F;Vue app.</p><p>Can’t wait to get recording!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Wow! We’re into 2018 already and I haven’t blogged for months and months. That’s such a shame because I’ve been doing so much cool stuff. So it’s time to get back on the horse!&lt;/p&gt;
&lt;h2 id=&quot;New-PWA-Pluralsight-Course-in-Flight&quot;&gt;&lt;a href=&quot;#New-PWA-Pluralsight-Course-in-Flight&quot; class=&quot;headerlink&quot; title=&quot;New PWA Pluralsight Course in Flight&quot;&gt;&lt;/a&gt;New PWA Pluralsight Course in Flight&lt;/h2&gt;&lt;p&gt;I’m presently working on new &lt;a href=&quot;https://app.pluralsight.com/profile/author/glen-smith&quot;&gt;Pluralsight Course&lt;/a&gt; related to Progressive Web Apps and Sensor Integration. I’m still scripting but there’s tons of cool stuff in there. &lt;/p&gt;
&lt;p&gt;It’s called Sights and Sounds&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2018/sights-sounds-scratchy-logo.png&quot; alt=&quot;Sights and Sounds Logo&quot;&gt;&lt;/p&gt;
&lt;p&gt;But not just any travel app. We’ll be developing a lightweight PWA on your handset and:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Taking photos;&lt;/li&gt;
&lt;li&gt;Recording videos;&lt;/li&gt;
&lt;li&gt;Lauching Notifications;&lt;/li&gt;
&lt;li&gt;Interacting with Fullscreen&lt;/li&gt;
&lt;li&gt;Doing Geo &amp;amp; directions;&lt;/li&gt;
&lt;li&gt;Launching native apps;&lt;/li&gt;
&lt;li&gt;Sensing network access and coping with it&lt;/li&gt;
&lt;li&gt;Doing offline sync magic with Firebase (including image upload)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I am so pumped about it. It’s pretty scratchy at the moment, but it’ll get there:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2018/sights-sounds-early-screengrab.jpg&quot; alt=&quot;Sights and Sounds Screenshot&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;Discovering-Polymer&quot;&gt;&lt;a href=&quot;#Discovering-Polymer&quot; class=&quot;headerlink&quot; title=&quot;Discovering Polymer&quot;&gt;&lt;/a&gt;Discovering Polymer&lt;/h2&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Polymer" scheme="http://blogs.bytecode.com.au/glen/tags/Polymer/"/>
    
  </entry>
  
  <entry>
    <title>Shrink Your Angular CLI Production Builds with Source Map Explorer</title>
    <link href="http://blogs.bytecode.com.au/glen/2017/11/03/source-map-explorer.html"/>
    <id>http://blogs.bytecode.com.au/glen/2017/11/03/source-map-explorer.html</id>
    <published>2017-11-03T02:41:27.000Z</published>
    <updated>2022-12-28T05:51:04.602Z</updated>
    
    <content type="html"><![CDATA[<p>So what’s really going on with all those dist&#x2F;*.bundle.js files that Webpack spits out of the Angular CLI generation process? </p><p>This video will give you a five minute way to have a look for yourself - and get ideas to shrink your production build sizes. The magic tool you need is <a href="https://github.com/danvk/source-map-explorer">Source Map Explorer</a>. </p><p>I learned this tip from Jim Cooper’s excellent Pluralsight course on “<a href="https://www.pluralsight.com/courses/best-practices-angular">Angular Best Practices</a>“ and thought it we be good to pass on in a way you can add to your own projects. </p><p>First then vid, or read on for the commands I added to <code>package.json</code>.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/nwu8gf9m-2A?rel=0" frameborder="0" allowfullscreen></iframe><p>First we’re going to install Source Map Explorer. I’m going to do things locally, since I like the idea of the project being self contained: </p><p><code>npm install source-map-explorer --save-dev --save-exact</code></p><p>Because <code>source-map-explorer</code> is a lot to type, I’ll create a little alias for it:</p><pre>"scripts": {    ...    "sme": "source-map-explorer"    ...}</pre><p>Now to use Source Map Explorer, you’re clearly going to need some source maps! You generate those by adding <code>--sourcemaps=true</code> to your prod build. To keep things DRY, I like to just decorate the <code>dist</code> target with my own <code>dist-with-maps</code> target. Something like this:</p><pre>"scripts": {    ...    "dist-with-maps": "npm run dist -- --sourcemaps=true",    ...}</pre><p>We’re all infrastructured up! So I’ll now run that new target so I can generate my source maps:</p><p><code>npm run dist-with-maps</code></p><p>Ok. Now we’re good to go. You should see a bunch of source maps in your &#x2F;dist directory now. </p><p>Let the sme magic commence!</p><p><code>npm run sme dist\vendor.ea432fea42.bundle.js</code></p><p>And remember you can click on areas to drill down, and then back on the headings to drill up!</p><p>Enjoy!</p><p><img src="/glen/glen/images/2017/source-map-explorer.jpg" alt="Source Map Explorer in Action"></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;So what’s really going on with all those dist&amp;#x2F;*.bundle.js files that Webpack spits out of the Angular CLI generation process? &lt;/p&gt;
&lt;p&gt;This video will give you a five minute way to have a look for yourself - and get ideas to shrink your production build sizes. The magic tool you need is &lt;a href=&quot;https://github.com/danvk/source-map-explorer&quot;&gt;Source Map Explorer&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;I learned this tip from Jim Cooper’s excellent Pluralsight course on “&lt;a href=&quot;https://www.pluralsight.com/courses/best-practices-angular&quot;&gt;Angular Best Practices&lt;/a&gt;“ and thought it we be good to pass on in a way you can add to your own projects. &lt;/p&gt;
&lt;p&gt;First then vid, or read on for the commands I added to &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/nwu8gf9m-2A?rel=0&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;First we’re going to install Source Map Explorer. I’m going to do things locally, since I like the idea of the project being self contained: &lt;/p&gt;
&lt;p&gt;&lt;code&gt;npm install source-map-explorer --save-dev --save-exact&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Because &lt;code&gt;source-map-explorer&lt;/code&gt; is a lot to type, I’ll create a little alias for it:&lt;/p&gt;
&lt;pre&gt;
&quot;scripts&quot;: {
    ...
    &quot;sme&quot;: &quot;source-map-explorer&quot;
    ...
}
&lt;/pre&gt;

&lt;p&gt;Now to use Source Map Explorer, you’re clearly going to need some source maps! You generate those by adding &lt;code&gt;--sourcemaps=true&lt;/code&gt; to your prod build. To keep things DRY, I like to just decorate the &lt;code&gt;dist&lt;/code&gt; target with my own &lt;code&gt;dist-with-maps&lt;/code&gt; target. Something like this:&lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Digital Detox for Programmers</title>
    <link href="http://blogs.bytecode.com.au/glen/2017/10/30/digital-detox.html"/>
    <id>http://blogs.bytecode.com.au/glen/2017/10/30/digital-detox.html</id>
    <published>2017-10-30T06:09:28.000Z</published>
    <updated>2022-12-28T05:51:04.602Z</updated>
    
    <content type="html"><![CDATA[<h1 id="We-need-to-talk-about-email"><a href="#We-need-to-talk-about-email" class="headerlink" title="We need to talk about email."></a>We need to talk about email.</h1><p>That’s what I wrote in my daily journal. </p><p>But really it was more about device checking. Desktop, Handset, whatever. </p><p>Constant. Device. Checking.</p><p>And I was exhausted. I needed an intervention.</p><h2 id="But…-I’m-a-programmer-right"><a href="#But…-I’m-a-programmer-right" class="headerlink" title="But… I’m a programmer, right?"></a>But… I’m a programmer, right?</h2><p>I get it. You <em>need</em> to be online, right? All the time, right?</p><p>I won’t speak for you, but living with this “constant on” mindset was just draining my batteries.</p><p>During the day the browser always had an email and twitter tab open.</p><p>My phone was always beside me in the evenings, just a quick check every so often for new email, twitter, and newsfeed action. Quick email replies and keep that inbox trimmed.</p><p>Getting more and more drained.</p><p>And that “always on” mindset wasn’t even <em>true</em>. People in my world are more than happy getting a reply in 24 hours (rather than 24 minutes). </p><p>Then Rob Bell came along..</p><p><img src="/glen/glen/images/2017/rob-bell-heavy-quote.jpg" alt="Just remember, if it&#39;s too heavy, you picked it up"></p><p>So I took action!</p><h2 id="Some-tools-to-help-with-the-Desktop-journey"><a href="#Some-tools-to-help-with-the-Desktop-journey" class="headerlink" title="Some tools to help with the Desktop journey"></a>Some tools to help with the Desktop journey</h2><p>The first step was to take the browser out of play during the work day. Those email, twitter and news tabs would have to go. For good.</p><p>Enter <a href="https://addons.mozilla.org/en-US/firefox/addon/leechblock/">Leechblock</a>. (I’m sure there’s a Chrome equivalent)</p><p><img src="/glen/glen/images/2017/leechblock-logo.png" alt="Leechblock stops browser distraction"></p><p>Leechblock lets me block groups of websites. First the ones that were killing me:</p><p><img src="/glen/glen/images/2017/leechblock-what.png" alt="My time suckers"></p><p>Then I could either configure things up by “allowed minutes”, or “time of day”. </p><p>I was going hardcore. Let’s just lock those sites down for most of the day.</p><p><img src="/glen/glen/images/2017/leechblock-when.png" alt="My time suckers"></p><p>Yes I could still cheat by going to other browsers. But honestly, it felt like cheating which meant it hasn’t been a problem.</p><p>Now, about that phone…</p><h2 id="Turning-your-Smartphone-into-a-Candybar…"><a href="#Turning-your-Smartphone-into-a-Candybar…" class="headerlink" title="Turning your Smartphone into a Candybar…"></a>Turning your Smartphone into a Candybar…</h2><p>The desktop filtering approach was working great. During work hours, it was a solid strategy.</p><p>But I realised that most of my drain was actually coming from after-hours. </p><p>So I wanted to go all in on blocking every dopamine thief on my phone handset..</p><p>Enter <a href="https://play.google.com/store/apps/details?id=cz.mobilesoft.appblock&hl=en">AppBlock</a>.</p><p><img src="/glen/glen/images/2017/appblock-logo.png" alt="Blocking Apps Hardcore"></p><p>This is when things really starting getting serious (and interesting). Now I could block both apps and notifications by time of day.</p><p>So I went even harder on the time allowances - since I already knew out-of-hours was where the big wins were to be had…</p><p><img src="/glen/glen/images/2017/appblock-by-time.jpg" alt="Blocking By Time"></p><p>Then I blocked every one of those energy thieves. </p><p>So what went on the list? All my access to email, Twitter, YouTube, eBay, Feedly, even Chrome! </p><p>Remember I still have access to Phone, SMS, Camera, Music, Podcasts &amp; Nav. And turns out that’s plenty.</p><p><img src="/glen/glen/images/2017/appblock-by-app.jpg" alt="Goodbye Dopamine Thieves"></p><p>As I said, I was going <em>all in</em>. </p><h2 id="The-results-so-far…"><a href="#The-results-so-far…" class="headerlink" title="The results so far…"></a>The results so far…</h2><p>I’ve been using the desktop browser block for a few months and loving it. Greatly improved focus during the day. Couple it with a Pomodoro approach, and you use your breaks for genuine recharge, not a mindless surfing&#x2F;checking cycle.</p><p>But the AppBlock install took things totally next level. I’ve only been doing that for two weeks and I’m <em>so</em> much more refreshed and creative. Should have done it years ago!</p><p>Maybe one day I’ll just ditch the whole handset :-) </p><p>Anyways, hope these tools are helpful in regulating your own online-ness.</p><p>If you have your own useful tools, <a href="https://twitter.com/glen_a_smith">tweet me up</a> (but I don’t check it that often, so be patient :-).</p>]]></content>
    
    
    <summary type="html">&lt;h1 id=&quot;We-need-to-talk-about-email&quot;&gt;&lt;a href=&quot;#We-need-to-talk-about-email&quot; class=&quot;headerlink&quot; title=&quot;We need to talk about email.&quot;&gt;&lt;/a&gt;We need to talk about email.&lt;/h1&gt;&lt;p&gt;That’s what I wrote in my daily journal. &lt;/p&gt;
&lt;p&gt;But really it was more about device checking. Desktop, Handset, whatever. &lt;/p&gt;
&lt;p&gt;Constant. Device. Checking.&lt;/p&gt;
&lt;p&gt;And I was exhausted. I needed an intervention.&lt;/p&gt;
&lt;h2 id=&quot;But…-I’m-a-programmer-right&quot;&gt;&lt;a href=&quot;#But…-I’m-a-programmer-right&quot; class=&quot;headerlink&quot; title=&quot;But… I’m a programmer, right?&quot;&gt;&lt;/a&gt;But… I’m a programmer, right?&lt;/h2&gt;&lt;p&gt;I get it. You &lt;em&gt;need&lt;/em&gt; to be online, right? All the time, right?&lt;/p&gt;
&lt;p&gt;I won’t speak for you, but living with this “constant on” mindset was just draining my batteries.&lt;/p&gt;
&lt;p&gt;During the day the browser always had an email and twitter tab open.&lt;/p&gt;
&lt;p&gt;My phone was always beside me in the evenings, just a quick check every so often for new email, twitter, and newsfeed action. Quick email replies and keep that inbox trimmed.&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>First Experiences with ngrx</title>
    <link href="http://blogs.bytecode.com.au/glen/2017/10/23/ngrx-experiences.html"/>
    <id>http://blogs.bytecode.com.au/glen/2017/10/23/ngrx-experiences.html</id>
    <published>2017-10-23T06:19:38.000Z</published>
    <updated>2022-12-28T05:51:04.602Z</updated>
    
    <content type="html"><![CDATA[<p>The last few months have been jam packed full of awesome. Totally living the dream right now.</p><p>On the back of my Pluralsight “<a href="https://www.pluralsight.com/courses/angular-apps-prime-ng">Building Beautiful Angular Apps with PrimeNG</a>“ course, I landed an awesome consulting gig building a very cool PrimeNG front-end.</p><p>The double-cool part of this gig is that the backend is totally asynchronous with lots of concurrent user changes coming over websockets. This was a great chance to apply a lot of the <a href="http://reactivex.io/rxjs/">RxJS</a> “Reactive Angular” stuff I’d been learning about over the last few months. That stuff is rocket fuel..</p><p>But everything has its limits.</p><p>I was soon lost in a maze of Observables and spiraling in a technical debt of state mutation.</p><p>Enter <a href="https://github.com/ngrx/platform">ngrx</a>.</p><p>If you haven’t bumped into ngrx before, it’s about applying the new hotness of <a href="https://github.com/reactjs/redux">Redux</a>-style applications to Angular, but built on <a href="http://reactivex.io/rxjs/">RxJS</a>. </p><p><img src="/glen/glen/images/2017/ngrx-logo.png" alt="ngrx eats state for breakfast"></p><h2 id="The-Benefits-of-ngrx"><a href="#The-Benefits-of-ngrx" class="headerlink" title="The Benefits of ngrx"></a>The Benefits of ngrx</h2><p>How does this ngrx stuff help my async plight?</p><ul><li>There’s now a <em>single</em> central place in my app where state lives. Everything goes through here!</li><li>That state is transformed through a set of pure reducer functions (think super easy to test since there’s no DI, just in and out)</li><li>Reducers are triggered by actions - simple async calls in my client code to say “Hey, I got a new piece of data, please add it to the store” or similar. </li><li>I can subscribe to changes in the parts of the store my component cares about (eg “tell me when the list of inventory changes”), at whatever points in my app need to listen for those changes</li></ul><h2 id="The-Refactor-Factor"><a href="#The-Refactor-Factor" class="headerlink" title="The Refactor Factor"></a>The Refactor Factor</h2><p>And what’s been the result in my refactor to ngrx?</p><ul><li>I ended up throwing out <em>tons</em> of code (always a good thing, especially the way I code :-)</li><li>The complexity level went through the floor (it was much easier to see where things were broken, since a lot of the code that was removed was “side-effect” style stuff which are replaced by ngrx Effects, or just plain reducers)</li><li>I could debug async stuff since I could see the flow of actions, and the mutations they were effecting</li></ul><p>But what’s really blown my mind has been the <a href="https://github.com/zalmoxisus/redux-devtools-extension">Redux Devtools</a> which work just great with ngrx.</p><p>Because all the store mutations are through returning fresh copies of the mutated store, you can use the dev tools to time travel! I can travel back in time inside my app to see what the state looked like before and after a particular event. Crazy, right!</p><h2 id="The-Dreaded-Learning-Curve…"><a href="#The-Dreaded-Learning-Curve…" class="headerlink" title="The Dreaded Learning Curve…"></a>The Dreaded Learning Curve…</h2><p>Yeah. That’s really been the only snag. There’s actually not too much “noob-level” ngrx tutorial stuff. And like everything JS, versions of things cycle like crazy, so lots of tutes get out of date very quickly.</p><p>I found Oren’s book <a href="http://www.apress.com/us/book/9781484226193">Reactive Programming with Angular and ngrx</a> to be super helpful on fundamentals. And particularly his rock star sample app – <a href="http://echoesplayer.com/">demo</a>, <a href="https://github.com/orizens/echoes-player">source</a>. Such great code in there!</p><p>I’m actually really keen to YouTube some basic screencasts around ngrx - at the noob level - that’s all I’ve unlocked! So if you think that would be helpful&#x2F;interesting, <a href="https://twitter.com/glen_a_smith">tweet me up</a>. </p><p>Will keep you posted..</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;The last few months have been jam packed full of awesome. Totally living the dream right now.&lt;/p&gt;
&lt;p&gt;On the back of my Pluralsight “&lt;a href=&quot;https://www.pluralsight.com/courses/angular-apps-prime-ng&quot;&gt;Building Beautiful Angular Apps with PrimeNG&lt;/a&gt;“ course, I landed an awesome consulting gig building a very cool PrimeNG front-end.&lt;/p&gt;
&lt;p&gt;The double-cool part of this gig is that the backend is totally asynchronous with lots of concurrent user changes coming over websockets. This was a great chance to apply a lot of the &lt;a href=&quot;http://reactivex.io/rxjs/&quot;&gt;RxJS&lt;/a&gt; “Reactive Angular” stuff I’d been learning about over the last few months. That stuff is rocket fuel..&lt;/p&gt;
&lt;p&gt;But everything has its limits.&lt;/p&gt;
&lt;p&gt;I was soon lost in a maze of Observables and spiraling in a technical debt of state mutation.&lt;/p&gt;
&lt;p&gt;Enter &lt;a href=&quot;https://github.com/ngrx/platform&quot;&gt;ngrx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you haven’t bumped into ngrx before, it’s about applying the new hotness of &lt;a href=&quot;https://github.com/reactjs/redux&quot;&gt;Redux&lt;/a&gt;-style applications to Angular, but built on &lt;a href=&quot;http://reactivex.io/rxjs/&quot;&gt;RxJS&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2017/ngrx-logo.png&quot; alt=&quot;ngrx eats state for breakfast&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;The-Benefits-of-ngrx&quot;&gt;&lt;a href=&quot;#The-Benefits-of-ngrx&quot; class=&quot;headerlink&quot; title=&quot;The Benefits of ngrx&quot;&gt;&lt;/a&gt;The Benefits of ngrx&lt;/h2&gt;&lt;p&gt;How does this ngrx stuff help my async plight?&lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>What&#39;s new?</title>
    <link href="http://blogs.bytecode.com.au/glen/2017/08/14/whats-new.html"/>
    <id>http://blogs.bytecode.com.au/glen/2017/08/14/whats-new.html</id>
    <published>2017-08-14T20:19:11.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Phew! It’s been a crazy few months and I have totally been off the blogging and the YouTube horse as I worked hard to get my first Pluralsight course off the ground: “Building Beautiful Angular Applications with PrimeNG”. </p><p>The great news is that <a href="https://www.pluralsight.com/">PluralSight</a> is pulling together the launch video right now - so we’re really, really close!</p><h2 id="So-what’s-next"><a href="#So-what’s-next" class="headerlink" title="So what’s next?"></a>So what’s next?</h2><p>That’s an awesome question. </p><p>And the answer is… more PrimeNG!</p><p>I’m excited to say that I’m currently working on a short-term commercial consulting gig using <a href="https://angular.io/">Angular</a>&#x2F;<a href="https://www.primefaces.org/primeng/">PrimeNG</a> - so I’m definitely dog-fooding my enthusiasm for both frameworks.</p><p><img src="/glen/glen/images/2017/messenger-dashboard.png" alt="PrimeNG for a living"></p><p>I’ve decided to move toward online teaching for the next season of my life - but I’ve always felt the best teachers are the ones working in the field, so it’s important to me to keep my hand in professional development work (outside of just “professional training”).</p><p>It’s actually been really confronting to sit down and work out a professional growth plan for myself as a programmer. 20 years in, and there’s still so many fundamentals that I get slack about.. (blog posts coming on “leveling up” soon..)</p><p>But that’s what’s so great about our profession. There is always a growth goal to stretch toward - or something new to learn - and the disruption never stops! </p><h2 id="And-the-Hobby-Mobile-project…"><a href="#And-the-Hobby-Mobile-project…" class="headerlink" title="And the Hobby Mobile project…"></a>And the Hobby Mobile project…</h2><p>I’ve promised a friend that I’d pull together a little PWA&#x2F;Mobile app to help him track his swim progress. I’ve been building it with Ionic and having a ball.</p><p>Really looking forward to spending more time with ServiceWorker this year. Some cool stuff to learn there..</p><p><img src="/glen/glen/images/2017/swim1000km-dashboard.jpg" alt="Hacking a PWA with Ionic 3"></p><h2 id="And-what’s-coming-up-on-the-blog"><a href="#And-what’s-coming-up-on-the-blog" class="headerlink" title="And what’s coming up on the blog?"></a>And what’s coming up on the blog?</h2><p>I’m hoping to explore a few themes here over the next month:</p><ul><li>Stuff I’m still learning about <a href="https://www.primefaces.org/primeng/">PrimeNG</a> (love that framework)</li><li>Some thinking about developing a personal growth plan for leveling up as a programmer</li><li>Things I’m learning about PWA&#x2F;Ionic to build for the Mobile Web</li></ul><p>That sounds like a bunch of cool stuff. Time to get cracking!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Phew! It’s been a crazy few months and I have totally been off the blogging and the YouTube horse as I worked hard to get my first Pluralsight course off the ground: “Building Beautiful Angular Applications with PrimeNG”. &lt;/p&gt;
&lt;p&gt;The great news is that &lt;a href=&quot;https://www.pluralsight.com/&quot;&gt;PluralSight&lt;/a&gt; is pulling together the launch video right now - so we’re really, really close!&lt;/p&gt;
&lt;h2 id=&quot;So-what’s-next&quot;&gt;&lt;a href=&quot;#So-what’s-next&quot; class=&quot;headerlink&quot; title=&quot;So what’s next?&quot;&gt;&lt;/a&gt;So what’s next?&lt;/h2&gt;&lt;p&gt;That’s an awesome question. &lt;/p&gt;
&lt;p&gt;And the answer is… more PrimeNG!&lt;/p&gt;
&lt;p&gt;I’m excited to say that I’m currently working on a short-term commercial consulting gig using &lt;a href=&quot;https://angular.io/&quot;&gt;Angular&lt;/a&gt;&amp;#x2F;&lt;a href=&quot;https://www.primefaces.org/primeng/&quot;&gt;PrimeNG&lt;/a&gt; - so I’m definitely dog-fooding my enthusiasm for both frameworks.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2017/messenger-dashboard.png&quot; alt=&quot;PrimeNG for a living&quot;&gt;&lt;/p&gt;
&lt;p&gt;I’ve decided to move toward online teaching for the next season of my life - but I’ve always felt the best teachers are the ones working in the field, so it’s important to me to keep my hand in professional development work (outside of just “professional training”).&lt;/p&gt;
&lt;p&gt;It’s actually been really confronting to sit down and work out a professional growth plan for myself as a programmer. 20 years in, and there’s still so many fundamentals that I get slack about.. (blog posts coming on “leveling up” soon..)&lt;/p&gt;
&lt;p&gt;But that’s what’s so great about our profession. There is always a growth goal to stretch toward - or something new to learn - and the disruption never stops! &lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>My PrimeNG Pluralsight Course - Now Recording</title>
    <link href="http://blogs.bytecode.com.au/glen/2017/04/26/click-record.html"/>
    <id>http://blogs.bytecode.com.au/glen/2017/04/26/click-record.html</id>
    <published>2017-04-26T03:44:45.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>The time has finally come!</p><p>After several weeks of scripting and code samples, the day has finally arrived to click record and get this show on the road. We’ve started recording this:</p><p><img src="/glen/glen/images/2017/building-beautiful-angular-applications-with-primeng.jpg" alt="Building Beautiful Angular Applications with PrimeNG"></p><p>The good news is that I’m really happy with how this course has shaped up, and I think developers are really going to warm to it.</p><p>Inside this course we build a… TADA… Enterprise Timesheeting app called “Agile Times”. This app gives us a great showcase of everything <a href="https://www.primefaces.org/primeng/">PrimeNG</a>.</p><p>We start out with learning about the Prime Grid system to create funky stats components for our Dashboard (thank you <a href="http://fontawesome.io/icons/">Font Awesome</a>), then dive into a world of snazzy charting to get your motivated.</p><p><img src="/glen/glen/images/2017/agile-times-dashboard.jpg" alt="Charting our Dashboard"></p><p>We then cover off all the common form controls people will want to use - all backed by Reactive Angular Forms to keep it real - along with matching DRY&#x2F;low-ceremony validation techniques!</p><p>With some early wins up our sleeve, we dive into filterable, sortable, searchable, paginatable data grids. To make is a bit more real-worldy, but without the overhead of installing 3rd party Dbs, we back our grid with a sizeable IndexedDb (powered by <a href="http://dexie.org/">Dexie</a>) to give us that familiar ORM-styling querying that devs will probably be using. Plus we can marvel at Prime’s Lazy Loading magic which keeps it all zippy.</p><p><img src="/glen/glen/images/2017/agile-times-datagrid.jpg" alt="Datagrids with Lazy Loading"></p><p>From there we head off into the less common controls such as Schedule, Trees, Google Maps, Wizards and Dialogs. Lots of fun stuff in there too!</p><p><img src="/glen/glen/images/2017/agile-times-dialog.jpg" alt="Less Common Controls"></p><p>Finally, we finish up by diving into some Advanced PrimeNG concepts. We dig into non-visual controls with Drag and Drop, explore how to Unit Test your PrimeNG app, and even dip our toes into the PrimeNG sourcecode to see how to work around things when you hit the wall.</p><p>I really hope developers are going to love this course - and that it builds some passion for <a href="https://www.primefaces.org/primeng/">PrimeNG</a>.</p><p>For now, it’s time for me to get back to recording. I’m only just getting started recording, and I need to get this course shipped off to post production in two weeks time!</p><p><img src="/glen/glen/images/2017/pluralsight-first-recording.jpg" alt="Get This Show On The Road"></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;The time has finally come!&lt;/p&gt;
&lt;p&gt;After several weeks of scripting and code samples, the day has finally arrived to click record and get this show on the road. We’ve started recording this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2017/building-beautiful-angular-applications-with-primeng.jpg&quot; alt=&quot;Building Beautiful Angular Applications with PrimeNG&quot;&gt;&lt;/p&gt;
&lt;p&gt;The good news is that I’m really happy with how this course has shaped up, and I think developers are really going to warm to it.&lt;/p&gt;
&lt;p&gt;Inside this course we build a… TADA… Enterprise Timesheeting app called “Agile Times”. This app gives us a great showcase of everything &lt;a href=&quot;https://www.primefaces.org/primeng/&quot;&gt;PrimeNG&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We start out with learning about the Prime Grid system to create funky stats components for our Dashboard (thank you &lt;a href=&quot;http://fontawesome.io/icons/&quot;&gt;Font Awesome&lt;/a&gt;), then dive into a world of snazzy charting to get your motivated.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2017/agile-times-dashboard.jpg&quot; alt=&quot;Charting our Dashboard&quot;&gt;&lt;/p&gt;
&lt;p&gt;We then cover off all the common form controls people will want to use - all backed by Reactive Angular Forms to keep it real - along with matching DRY&amp;#x2F;low-ceremony validation techniques!&lt;/p&gt;
&lt;p&gt;With some early wins up our sleeve, we dive into filterable, sortable, searchable, paginatable data grids. To make is a bit more real-worldy, but without the overhead of installing 3rd party Dbs, we back our grid with a sizeable IndexedDb (powered by &lt;a href=&quot;http://dexie.org/&quot;&gt;Dexie&lt;/a&gt;) to give us that familiar ORM-styling querying that devs will probably be using. Plus we can marvel at Prime’s Lazy Loading magic which keeps it all zippy.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2017/agile-times-datagrid.jpg&quot; alt=&quot;Datagrids with Lazy Loading&quot;&gt;&lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>PrimeNG defaulting chart colours</title>
    <link href="http://blogs.bytecode.com.au/glen/2017/03/15/primeng-chart-colours.html"/>
    <id>http://blogs.bytecode.com.au/glen/2017/03/15/primeng-chart-colours.html</id>
    <published>2017-03-15T03:37:55.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>I’m deep into a Pluralsight course on PrimeNG, and have started to cover some of the niceties of PrimeNG charts.</p><p>The charting component is a wrapper around <a href="http://chartjs.org/docs/">Chart.js</a>, and one of the.. um.. interesting parts of the very cool Chart.js is that it has no default slice&#x2F;bar colours.</p><p>Turns out this is a <a href="https://github.com/chartjs/Chart.js/issues/815">much requested feature</a> and someone on that very thread went to the trouble of putting together a nice set of colours based around Google Charts.</p><p>But…</p><p>I don’t want to hand-assign the colours each time.</p><p>So.. </p><p>The challenge: Write a function that will take an arbitrarily long pie chart dataset, and assign funky complimentary chart colours to each slice (so that the colour selection wraps around after depleting the set of funky colours).</p><p>Here’s my stab. First, setup a constant at the top of your TypeScript controller:</p><pre><code>    const DEFAULT_COLORS = [&#39;#3366CC&#39;, &#39;#DC3912&#39;, &#39;#FF9900&#39;, &#39;#109618&#39;, &#39;#990099&#39;,    &#39;#3B3EAC&#39;, &#39;#0099C6&#39;, &#39;#DD4477&#39;, &#39;#66AA00&#39;, &#39;#B82E2E&#39;,    &#39;#316395&#39;, &#39;#994499&#39;, &#39;#22AA99&#39;, &#39;#AAAA11&#39;, &#39;#6633CC&#39;,    &#39;#E67300&#39;, &#39;#8B0707&#39;, &#39;#329262&#39;, &#39;#5574A6&#39;, &#39;#3B3EAC&#39;]</code></pre><p>Then inside the class, setup a routine to map the dataset into our set of default colours for each pie:</p><pre><code>    private configureDefaultColours(data: number[]): string[] &#123;        let customColours = []        if (data.length) &#123;        customColours = data.map((element, idx) =&gt; &#123;            return DEFAULT_COLORS[idx % DEFAULT_COLORS.length];        &#125;);        &#125;        return customColours;    &#125;</code></pre><p>Then last of all, call that routine with your data whenever you need to generate some colours for your chart, and you’ll get back an array of colours to keep things fresh:</p><pre><code>    private hoursByProject = [        &#123;id: 1, name: &#39;Payroll App&#39;, hoursSpent: 8&#125;,        &#123;id: 2, name: &#39;Agile Times App&#39;, hoursSpent: 16&#125;,        &#123;id: 3, name: &#39;Point of Sale App&#39;, hoursSpent: 24&#125;,    ]    private pieData = this.hoursByProject.map((proj) =&gt; proj.hoursSpent);    private pieLabels = this.hoursByProject.map((proj) =&gt; proj.name);    private pieColors = this.configureDefaultColours(this.pieData);    private hoursByProjectChartData = &#123;        labels: this.pieLabels,        datasets: [        &#123;            data: this.pieData,            backgroundColor: this.pieColors,        &#125;        ]    &#125;;</code></pre><p>And you have yourself a chart with some funky default colours… Voila!</p><p><img src="/glen/glen/images/2017/hours-by-project-chart.png" alt="Bring the Colours On"></p><p>If you love this sort of stuff, you’ll probably enjoy my upcoming Pluralsight course on PrimeNG! Stay tuned!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;I’m deep into a Pluralsight course on PrimeNG, and have started to cover some of the niceties of PrimeNG charts.&lt;/p&gt;
&lt;p&gt;The charting component is a wrapper around &lt;a href=&quot;http://chartjs.org/docs/&quot;&gt;Chart.js&lt;/a&gt;, and one of the.. um.. interesting parts of the very cool Chart.js is that it has no default slice&amp;#x2F;bar colours.&lt;/p&gt;
&lt;p&gt;Turns out this is a &lt;a href=&quot;https://github.com/chartjs/Chart.js/issues/815&quot;&gt;much requested feature&lt;/a&gt; and someone on that very thread went to the trouble of putting together a nice set of colours based around Google Charts.&lt;/p&gt;
&lt;p&gt;But…&lt;/p&gt;
&lt;p&gt;I don’t want to hand-assign the colours each time.&lt;/p&gt;
&lt;p&gt;So.. &lt;/p&gt;
&lt;p&gt;The challenge: Write a function that will take an arbitrarily long pie chart dataset, and assign funky complimentary chart colours to each slice (so that the colour selection wraps around after depleting the set of funky colours).&lt;/p&gt;
&lt;p&gt;Here’s my stab. First, setup a constant at the top of your TypeScript controller:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;    const DEFAULT_COLORS = [&amp;#39;#3366CC&amp;#39;, &amp;#39;#DC3912&amp;#39;, &amp;#39;#FF9900&amp;#39;, &amp;#39;#109618&amp;#39;, &amp;#39;#990099&amp;#39;,
    &amp;#39;#3B3EAC&amp;#39;, &amp;#39;#0099C6&amp;#39;, &amp;#39;#DD4477&amp;#39;, &amp;#39;#66AA00&amp;#39;, &amp;#39;#B82E2E&amp;#39;,
    &amp;#39;#316395&amp;#39;, &amp;#39;#994499&amp;#39;, &amp;#39;#22AA99&amp;#39;, &amp;#39;#AAAA11&amp;#39;, &amp;#39;#6633CC&amp;#39;,
    &amp;#39;#E67300&amp;#39;, &amp;#39;#8B0707&amp;#39;, &amp;#39;#329262&amp;#39;, &amp;#39;#5574A6&amp;#39;, &amp;#39;#3B3EAC&amp;#39;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then inside the class, setup a routine to map the dataset into our set of default colours for each pie:&lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>PrimeNG is coming to Pluralsight</title>
    <link href="http://blogs.bytecode.com.au/glen/2017/03/10/primeng-on-pluralsight.html"/>
    <id>http://blogs.bytecode.com.au/glen/2017/03/10/primeng-on-pluralsight.html</id>
    <published>2017-03-10T03:11:53.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>As you may know, I’ve been a big fan of <a href="https://www.primefaces.org/primeng">PrimeNG</a> for some time (and Primefaces before that!), so I’m super excited to announce that I’ve officially inked the paperwork and started working on a course for <a href="https://www.pluralsight.com/">Pluralsight</a> around PrimeNG. </p><p><img src="/glen/glen/images/2017/agile-times.png" alt="Agile Times with PrimeNG"></p><p>I’ve done a bunch of <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">YouTube</a> training videos before, but have always wanted to try my hand at the Pluralsight training thing since I’ve always loved their style. </p><p>Pluralsight really do have a super high bar for production quality, so I’m looking forward to stretching out and leveling up my online training skills - which will also benefit my YouTube channel!</p><p>I’ve spend today digging into the sample code for the Charting module, where I’ll be teaching charting “from zero to hero” culminating with coding up real-time, mixed style charts like this bad boy:</p><p><img src="/glen/glen/images/2017/primeng-realtime-charts.gif" alt="Multiple Chart Types with Dynamic Refresh"></p><p>As a side effect, I know finally understand <a href="https://www.learnrxjs.io/operators/transformation/switchmap.html"><code>switchMap()</code></a> in RxJS! So much winning!</p><p>Anyways, can’t wait to get started recording. Will keep you all posted on the progress over the next two months or so.</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;As you may know, I’ve been a big fan of &lt;a href=&quot;https://www.primefaces.org/primeng&quot;&gt;PrimeNG&lt;/a&gt; for some time (and Primefaces before that!), so I’m super excited to announce that I’ve officially inked the paperwork and started working on a course for &lt;a href=&quot;https://www.pluralsight.com/&quot;&gt;Pluralsight&lt;/a&gt; around PrimeNG. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2017/agile-times.png&quot; alt=&quot;Agile Times with PrimeNG&quot;&gt;&lt;/p&gt;
&lt;p&gt;I’ve done a bunch of &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;YouTube&lt;/a&gt; training videos before, but have always wanted to try my hand at the Pluralsight training thing since I’ve always loved their style. &lt;/p&gt;
&lt;p&gt;Pluralsight really do have a super high bar for production quality, so I’m looking forward to stretching out and leveling up my online training skills - which will also benefit my YouTube channel!&lt;/p&gt;
&lt;p&gt;I’ve spend today digging into the sample code for the Charting module, where I’ll be teaching charting “from zero to hero” culminating with coding up real-time, mixed style charts like this bad boy:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2017/primeng-realtime-charts.gif&quot; alt=&quot;Multiple Chart Types with Dynamic Refresh&quot;&gt;&lt;/p&gt;
&lt;p&gt;As a side effect, I know finally understand &lt;a href=&quot;https://www.learnrxjs.io/operators/transformation/switchmap.html&quot;&gt;&lt;code&gt;switchMap()&lt;/code&gt;&lt;/a&gt; in RxJS! So much winning!&lt;/p&gt;
&lt;p&gt;Anyways, can’t wait to get started recording. Will keep you all posted on the progress over the next two months or so.&lt;/p&gt;
</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Configuring PrimeNG Charting with Angular CLI</title>
    <link href="http://blogs.bytecode.com.au/glen/2017/02/23/primeng-charting.html"/>
    <id>http://blogs.bytecode.com.au/glen/2017/02/23/primeng-charting.html</id>
    <published>2017-02-23T08:15:50.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Just a quick one for those struggling to get the PrimeNG charting components rendering. You might be importing the ChartModule just fine, and even setting up your component tags and data, but all you’re getting in the console is something like:</p><pre><code>Error: Error in ./DashboardComponent class DashboardComponent - inline template:22:4 caused by: Chart is not defined</code></pre><p>The bit of info you’re missing is that all of the PrimeNG charting components rely on you bundling <a href="http://www.chartjs.org/">Chart.js</a> with your application. That’s the JavaScript library that supplies the Chart in <code>Chart is not defined</code>.</p><p>The easiest way to do that with Angular CLI is to first install the NPM package with:</p><pre><code>npm install chart.js --save</code></pre><p>Then bundle the library with your build by editing the angular-cli.json file in your root directory to include it in the <code>scripts</code> array like so:</p><pre><code>&quot;scripts&quot;: [    &quot;../node_modules/chart.js/dist/Chart.js&quot;  ], </code></pre><p>With those in-place, you’ll be ready to Chart up a storm.</p><p>Have fun!</p><p><img src="/glen/glen/images/2017/primeng-charting.png" alt="Now you know the hack"></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Just a quick one for those struggling to get the PrimeNG charting components rendering. You might be importing the ChartModule just fine, and even setting up your component tags and data, but all you’re getting in the console is something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Error: Error in ./DashboardComponent class DashboardComponent - inline template:22:4 caused by: Chart is not defined
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The bit of info you’re missing is that all of the PrimeNG charting components rely on you bundling &lt;a href=&quot;http://www.chartjs.org/&quot;&gt;Chart.js&lt;/a&gt; with your application. That’s the JavaScript library that supplies the Chart in &lt;code&gt;Chart is not defined&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;The easiest way to do that with Angular CLI is to first install the NPM package with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install chart.js --save
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then bundle the library with your build by editing the angular-cli.json file in your root directory to include it in the &lt;code&gt;scripts&lt;/code&gt; array like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;quot;scripts&amp;quot;: [
    &amp;quot;../node_modules/chart.js/dist/Chart.js&amp;quot;
  ], 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With those in-place, you’ll be ready to Chart up a storm.&lt;/p&gt;
&lt;p&gt;Have fun!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2017/primeng-charting.png&quot; alt=&quot;Now you know the hack&quot;&gt;&lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Using JQuery (and Semantic UI) with Angular CLI</title>
    <link href="http://blogs.bytecode.com.au/glen/2017/02/15/jquery-with-angular-cli.html"/>
    <id>http://blogs.bytecode.com.au/glen/2017/02/15/jquery-with-angular-cli.html</id>
    <published>2017-02-15T00:00:08.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>I keep solving this problem, so it’s time to write it down for my future self!</p><p>I know your story. You want to use jQuery inside an Angular CLI app, but the whole WebPack magic is turning everything bad. </p><p>Or perhaps things are even more complex. You want to use a 3rd party product, like <a href="http://semantic-ui.com/">Semantic UI</a>, which augments existing jQuery objects in global scope, from your Angular CLI app, and it’s not happening for you.</p><p>Your web searches are awash with old advice. </p><p>This is the page you have been looking for. </p><p>Here’s something that works with <code>1.0.0-beta.31</code> of the CLI (and probably earlier WebPack-based versions too).</p><h2 id="Watch-the-vid-on-YouTube-or-scroll-down-for-the-steps-in-text-form"><a href="#Watch-the-vid-on-YouTube-or-scroll-down-for-the-steps-in-text-form" class="headerlink" title="Watch the vid on YouTube, or scroll down for the steps in text form"></a>Watch the vid on YouTube, or scroll down for the steps in text form</h2><iframe width="560" height="315" src="https://www.youtube.com/embed/4jeIKW6SN0A" frameborder="0" allowfullscreen></iframe><h2 id="First-npm-install-the-libraries-you-need"><a href="#First-npm-install-the-libraries-you-need" class="headerlink" title="First, npm install the libraries you need"></a>First, <code>npm install</code> the libraries you need</h2><p>In my case, I’m working with Semantic UI. This framework both has CSS and JS component - and depends on jQuery for heavy lifting. </p><p>So I need npm install those libs first.</p><pre><code>npm install jquery --savenpm install semantic-ui-css --save</code></pre><p>Once those are installed, you should be able to spy them in the <code>./node_modules/</code> directory in the root of your project.</p><p>All good so far.</p><h2 id="Next-import-your-global-JS-libs-in-browser-global-scope-using-angular-cli-json"><a href="#Next-import-your-global-JS-libs-in-browser-global-scope-using-angular-cli-json" class="headerlink" title="Next, import your global JS libs in browser global scope using angular-cli.json"></a>Next, import your global JS libs in browser global scope using angular-cli.json</h2><p>You’ll find a <code>angular-cli.json</code> in the root directory of your project. This is the config file for the CLI, and you can tell the CLI about your global styles and JS there.</p><p>You’ll need to make insertions in the <code>styles</code> and <code>scripts</code> arrays. Here’s the extract from mine that deals with the CSS and JS I need:</p><pre><code>&quot;styles&quot;: [    &quot;styles.css&quot;,    &quot;../node_modules/semantic-ui-css/semantic.css&quot;  ],  &quot;scripts&quot;: [    &quot;../node_modules/jquery/dist/jquery.js&quot;,    &quot;../node_modules/semantic-ui-css/semantic.js&quot;  ],        </code></pre><p>You notice I slurped in my global styles in the <code>styles</code> section - and they are the path to the <code>node_modules</code> we installed earlier. The path is double-dot &#96;..&#x2F;node_modules&#x2F;‘ remember.</p><p>Same for the <code>scripts</code> block. Import what you need and you’re set.</p><h2 id="Finally-declare-the-global-JavaScript-to-your-TypeScript"><a href="#Finally-declare-the-global-JavaScript-to-your-TypeScript" class="headerlink" title="Finally, declare the global JavaScript to your TypeScript"></a>Finally, declare the global JavaScript to your TypeScript</h2><p>In my case, Semantic is augmenting the existing jQuery object, so I’ll need to “declare” that global variable so TypeScript knows about it. </p><p>For that you need a line like this at the top of your class file:</p><pre><code>declare var jQuery: any;</code></pre><p>And with that inplace, you can now call the <code>jQuery()</code> methods you’ve been looking for.</p><p>Note: You don’t need any <code>&lt;link&gt;</code> or <code>&lt;script&gt;</code> tags. The CLI&#x2F;WebPack has done all the bundling work for you. Just start using stuff!</p><p>So, for example, to invoke the SideNav from Semantic UI, you’d normally call the <code>sidebar()</code> method on the jQuery object. </p><p>Here’s the full sample code (with that <code>declare</code> magic) to follow along at home:</p><pre><code>import &#123; Component &#125; from &#39;@angular/core&#39;;declare var jQuery: any;@Component(&#123;selector: &#39;app-root&#39;,templateUrl: &#39;./app.component.html&#39;,styleUrls: [&#39;./app.component.css&#39;]&#125;)export class AppComponent &#123;    title = &#39;jQuery works!&#39;;    onToggle() &#123;        jQuery(&#39;.ui.sidebar&#39;).sidebar(&#39;setting&#39;, &#39;transition&#39;, &#39;push&#39;).sidebar(&#39;toggle&#39;);    &#125;&#125;</code></pre><p>And the matching HTML that it’s invoking:</p><pre><code>&lt;h1&gt;&#123;&#123;title&#125;&#125;&lt;/h1&gt;&lt;div class=&quot;ui left demo vertical inverted sidebar labeled icon menu&quot; id=&quot;sidenav&quot;&gt;&lt;a class=&quot;item&quot;&gt;    &lt;i class=&quot;home icon&quot;&gt;&lt;/i&gt;    Home&lt;/a&gt;&lt;a class=&quot;item&quot;&gt;    &lt;i class=&quot;block layout icon&quot;&gt;&lt;/i&gt;    Topics&lt;/a&gt;&lt;a class=&quot;item&quot;&gt;    &lt;i class=&quot;smile icon&quot;&gt;&lt;/i&gt;    Friends&lt;/a&gt;&lt;/div&gt;&lt;button (click)=&quot;onToggle()&quot;&gt;Toggle Me&lt;/button&gt;</code></pre><p>Which gives you the goodness:</p><p><img src="/glen/glen/images/2017/jquery-angular-cli.gif" alt="jQuery with Angular CLI"></p><p>Hope it helps next time you need jQuery (or Semantic UI) in your Angular CLI app!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;I keep solving this problem, so it’s time to write it down for my future self!&lt;/p&gt;
&lt;p&gt;I know your story. You want to use jQuery inside an Angular CLI app, but the whole WebPack magic is turning everything bad. &lt;/p&gt;
&lt;p&gt;Or perhaps things are even more complex. You want to use a 3rd party product, like &lt;a href=&quot;http://semantic-ui.com/&quot;&gt;Semantic UI&lt;/a&gt;, which augments existing jQuery objects in global scope, from your Angular CLI app, and it’s not happening for you.&lt;/p&gt;
&lt;p&gt;Your web searches are awash with old advice. &lt;/p&gt;
&lt;p&gt;This is the page you have been looking for. &lt;/p&gt;
&lt;p&gt;Here’s something that works with &lt;code&gt;1.0.0-beta.31&lt;/code&gt; of the CLI (and probably earlier WebPack-based versions too).&lt;/p&gt;
&lt;h2 id=&quot;Watch-the-vid-on-YouTube-or-scroll-down-for-the-steps-in-text-form&quot;&gt;&lt;a href=&quot;#Watch-the-vid-on-YouTube-or-scroll-down-for-the-steps-in-text-form&quot; class=&quot;headerlink&quot; title=&quot;Watch the vid on YouTube, or scroll down for the steps in text form&quot;&gt;&lt;/a&gt;Watch the vid on YouTube, or scroll down for the steps in text form&lt;/h2&gt;&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/4jeIKW6SN0A&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;h2 id=&quot;First-npm-install-the-libraries-you-need&quot;&gt;&lt;a href=&quot;#First-npm-install-the-libraries-you-need&quot; class=&quot;headerlink&quot; title=&quot;First, npm install the libraries you need&quot;&gt;&lt;/a&gt;First, &lt;code&gt;npm install&lt;/code&gt; the libraries you need&lt;/h2&gt;&lt;p&gt;In my case, I’m working with Semantic UI. This framework both has CSS and JS component - and depends on jQuery for heavy lifting. &lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular Masterclass Day 3 and Final Retro</title>
    <link href="http://blogs.bytecode.com.au/glen/2017/01/11/angular-2-masterclass-day-three.html"/>
    <id>http://blogs.bytecode.com.au/glen/2017/01/11/angular-2-masterclass-day-three.html</id>
    <published>2017-01-11T19:31:04.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>After a day of Observables on <a href="/glen/2017/01/11/angular-2-masterclass-day-two.html">Day Two</a>, the final day of the <a href="http://thoughtram.io/angular-master-class.html">Masterclass</a> was focused around forms and routing.   </p><p>Here’s my typo-laden gitlog for the day to give you an idea of content pace and the type of exercises we worked on:</p><p><img src="/glen/glen/images/2017/angular-day3-git-log.png" alt="Day 3 Gitlog Doesn&#39;t Lie"></p><h2 id="Both-Kinds-of-Music-Template-and-Reactive-forms"><a href="#Both-Kinds-of-Music-Template-and-Reactive-forms" class="headerlink" title="Both Kinds of Music: Template and Reactive forms"></a>Both Kinds of Music: Template and Reactive forms</h2><p>A good portion of the day was spent working with both Template-Driven and Reactive Forms in Angular - and getting a really good feel for where each of them shine. </p><p>I’ve never been much of a fan of Reactive Forms - they seemed like a separation of concerns that I didn’t want to separate - but I have a new respect for them after yesterday (I particularly love the idea of being able to unit test that validation magic in a vanilla unit test).</p><p>I now like both approaches - and look forward to road testing both in larger forms apps to give me a real feel for what has the lowest friction.</p><p>Here’s the vanity screencast of yesterday’s hacking efforts:</p><p><img src="/glen/glen/images/2017/thoughtram-day3-sample.gif" alt="A Survey of Day 3"></p><p>We also wrote our first custom validator - and used it in both Template and Reactive approaches. Validation code is another area where Reactive’s <a href="https://angular.io/docs/ts/latest/api/forms/index/FormBuilder-class.html">FormBuilder</a> really shines - super straightforward and clear to read afterwards.</p><h2 id="Then-on-to-Child-Routes-and-Laziness"><a href="#Then-on-to-Child-Routes-and-Laziness" class="headerlink" title="Then on to Child Routes and Laziness"></a>Then on to Child Routes and Laziness</h2><p>With our forms experiments behind us, it was on to master&#x2F;detail child routing - which was really great to see in action (I’d read about it, but never had a reason to experiment with it). We had a top level of routing for our menu, then a master&#x2F;detail child route looking after our Contacts List -&gt; Detail Detail&#x2F;Editor connection. Super great.</p><p>We finished the day exploring lazy loading of routes, then a little about AOT Compilation before I had to leave early to catch the last flight to Canberra.</p><h2 id="Overall"><a href="#Overall" class="headerlink" title="Overall?"></a>Overall?</h2><p>So was it worth it? Travel costs, Accommodation, Course fees, Time off, etc?</p><p>Absolutely. And on so many fronts:</p><ul><li><strong>Super high-bandwidth classmates</strong>. Confirmation bias? :-) The type of developer that’s attracted to a course like this is already a, well, little self-selecting. Everyone was deep-ending tech all over the place and experimenting with different approaches to things (check out Phil’s Post on <a href="https://medium.com/@pmccloghrylaing/angular-2-pipes-error-messages-eec8e70120a4#.4a5lfhz2t">Piping Errors</a>).  Just hanging out with that set of folk was stretching!</li><li><strong>Super high-bandwidth instructors</strong>. Up-to-the minute instruction on latest best practices and emerging approaches. And friendly and approachable as well (we went out for drinks as a several times together as a class just to hang out)! And being committers in ecosystem projects made everything grounded in reality of daily grind (which is super helpful).</li><li><strong>Multiple Instructors</strong>. I’m really sold on this approach. Not only does it give you multiple perspectives and backgrounds, switching up the talking head keeps things fresh and moving.</li><li><strong>Great exercises</strong>. The tasks were clear in what you needed to do, but left you to work out how to do it. There was no “bounding ball” to follow - you had to draw on the courseware, colleagues, and experimenting to get you there. That really forces you to collaborate and learn the stuff (and provides interesting sidetracks along the way). </li><li><strong>Evergreen courseware</strong>. Lifetime access to evolving course materials, exercises and solutions is awesome. This is a super cool benefit in the fast-moving Angular landscape. </li><li><strong>Pure Focus</strong>. For professional development, I’m convinced that nothing beats being in a high-bandwidth focused “in person” training environment. I love video training (and will be both giving and consuming plenty of it this year), but there’s nothing like being in a class of motivated people forcing yourself to do the work.</li></ul><p>This was a five star training experience. Six stars if you can do it in Sydney ;-)</p><p>Many thanks to thoughtram for coming over! </p><p>Recommended.</p><p><img src="/glen/glen/images/2017/sydney-harbour-bridge.jpg" alt="View of the Sydney Harbour Bridge"></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;After a day of Observables on &lt;a href=&quot;/glen/2017/01/11/angular-2-masterclass-day-two.html&quot;&gt;Day Two&lt;/a&gt;, the final day of the &lt;a href=&quot;http://thoughtram.io/angular-master-class.html&quot;&gt;Masterclass&lt;/a&gt; was focused around forms and routing.   &lt;/p&gt;
&lt;p&gt;Here’s my typo-laden gitlog for the day to give you an idea of content pace and the type of exercises we worked on:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2017/angular-day3-git-log.png&quot; alt=&quot;Day 3 Gitlog Doesn&amp;#39;t Lie&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;Both-Kinds-of-Music-Template-and-Reactive-forms&quot;&gt;&lt;a href=&quot;#Both-Kinds-of-Music-Template-and-Reactive-forms&quot; class=&quot;headerlink&quot; title=&quot;Both Kinds of Music: Template and Reactive forms&quot;&gt;&lt;/a&gt;Both Kinds of Music: Template and Reactive forms&lt;/h2&gt;&lt;p&gt;A good portion of the day was spent working with both Template-Driven and Reactive Forms in Angular - and getting a really good feel for where each of them shine. &lt;/p&gt;
&lt;p&gt;I’ve never been much of a fan of Reactive Forms - they seemed like a separation of concerns that I didn’t want to separate - but I have a new respect for them after yesterday (I particularly love the idea of being able to unit test that validation magic in a vanilla unit test).&lt;/p&gt;
&lt;p&gt;I now like both approaches - and look forward to road testing both in larger forms apps to give me a real feel for what has the lowest friction.&lt;/p&gt;
&lt;p&gt;Here’s the vanity screencast of yesterday’s hacking efforts:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2017/thoughtram-day3-sample.gif&quot; alt=&quot;A Survey of Day 3&quot;&gt;&lt;/p&gt;
&lt;p&gt;We also wrote our first custom validator - and used it in both Template and Reactive approaches. Validation code is another area where Reactive’s &lt;a href=&quot;https://angular.io/docs/ts/latest/api/forms/index/FormBuilder-class.html&quot;&gt;FormBuilder&lt;/a&gt; really shines - super straightforward and clear to read afterwards.&lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular Masterclass Day 2 Retro</title>
    <link href="http://blogs.bytecode.com.au/glen/2017/01/10/angular-2-masterclass-day-two.html"/>
    <id>http://blogs.bytecode.com.au/glen/2017/01/10/angular-2-masterclass-day-two.html</id>
    <published>2017-01-10T19:57:10.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Wow. Things just got seriously master-level at the <a href="(http://thoughtram.io/angular-master-class.html">Masterclass</a>! Day Two really did build on <a href="/glen/2017/01/10/angular-2-masterclass-day-one.html">Day One</a>, kicking off with the wonders of the <a href="https://angular.io/docs/ts/latest/api/common/index/AsyncPipe-pipe.html">Async pipe</a>.  </p><p>It was actually great to start out with Async Pipe, since it let us convert our little Contacts application to an Observable architecture and ditch all the dodgy <code>*ngIf</code> code and null checking we’d crammed into to play nice with the async http calls.</p><h2 id="Getting-Serious-With-Observables"><a href="#Getting-Serious-With-Observables" class="headerlink" title="Getting Serious With Observables"></a>Getting Serious With Observables</h2><p>Async was really the theme for the day, and the exercises came steadily throughout the day to make sure we were grabbing the concepts as they were introduced. There’s a lot to love about Observables, but it took the day to really appreciate what they bring to the table.</p><p>Here’s my typo-laden gitlog for the day to give you an idea of content pace and the type of exercises we worked on:</p><p><img src="/glen/glen/images/2017/angular-day2-git-log.png" alt="Day 2 Gitlog Doesn&#39;t Lie"></p><h2 id="Making-friends-with-RxJS-switchMap-takeUntil-Oh-My"><a href="#Making-friends-with-RxJS-switchMap-takeUntil-Oh-My" class="headerlink" title="Making friends with RxJS - switchMap(), takeUntil(), Oh My!"></a>Making friends with RxJS - switchMap(), takeUntil(), Oh My!</h2><p>Christoph and Thomas took us on a tour of the hardcore range of Rx operators that are helpful when working with Observables. Even with marble diagrams, some of these concepts pretty much blew our minds! </p><p>Major. Paradigm. Shift.</p><p>As a last mic drop before the <code>switchMap()</code> exercise Christoph told us “you’ll work it out” - then pointed it at the lab to learn-by-doing.</p><p>And work it out we did. We implemented the classic <code>debounceTime()</code> search scenario (but optimised it with a little <code>distinctUntilChanged()</code>, followed up with some <code>merge()</code>ing with the initial ContactList <code>Http</code> fetch for the non-search case, and even sprinkled in some serious <code>switchMap()</code> rocket surgery to make sure that async fetches arriving out of sequence were handled (to cater for load balancing scenarios).</p><p>It was impressive.</p><p>And it will take a lot more practice.</p><p>But here’s a vanity showoff of what we covered today.</p><p><img src="/glen/glen/images/2017/thoughtram-day2-sample.gif" alt="A Survey of Day 2"></p><p>As one of the many bonuses, I finally understand why you use this form of import for RxJS (compared with the standard Angular imports): </p><pre><code>import &#39;rxjs/add/operator/map&#39;;</code></pre><h2 id="Intercomponent-Comms-turned-up-to-11"><a href="#Intercomponent-Comms-turned-up-to-11" class="headerlink" title="Intercomponent Comms turned up to 11"></a>Intercomponent Comms turned up to 11</h2><p>We did all kinds of intercomponent comms yesterday - property binding, <code>EventEmitter</code>, and all their friends were covered - culminating in implementing a basic EventBus shell. Powered by a <code>Subject()</code>, this EventBusService let us update the Header component of our application with a breadcrumb from wherever we were in the app. Very nifty!</p><h2 id="Bring-On-Day-Three"><a href="#Bring-On-Day-Three" class="headerlink" title="Bring On Day Three"></a>Bring On Day Three</h2><p>Today we dive into all the nuances of Forms and Validation and will be getting deep into the Router for routing child views. Great way to finish!</p><p>Pumped!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Wow. Things just got seriously master-level at the &lt;a href=&quot;(http://thoughtram.io/angular-master-class.html&quot;&gt;Masterclass&lt;/a&gt;! Day Two really did build on &lt;a href=&quot;/glen/2017/01/10/angular-2-masterclass-day-one.html&quot;&gt;Day One&lt;/a&gt;, kicking off with the wonders of the &lt;a href=&quot;https://angular.io/docs/ts/latest/api/common/index/AsyncPipe-pipe.html&quot;&gt;Async pipe&lt;/a&gt;.  &lt;/p&gt;
&lt;p&gt;It was actually great to start out with Async Pipe, since it let us convert our little Contacts application to an Observable architecture and ditch all the dodgy &lt;code&gt;*ngIf&lt;/code&gt; code and null checking we’d crammed into to play nice with the async http calls.&lt;/p&gt;
&lt;h2 id=&quot;Getting-Serious-With-Observables&quot;&gt;&lt;a href=&quot;#Getting-Serious-With-Observables&quot; class=&quot;headerlink&quot; title=&quot;Getting Serious With Observables&quot;&gt;&lt;/a&gt;Getting Serious With Observables&lt;/h2&gt;&lt;p&gt;Async was really the theme for the day, and the exercises came steadily throughout the day to make sure we were grabbing the concepts as they were introduced. There’s a lot to love about Observables, but it took the day to really appreciate what they bring to the table.&lt;/p&gt;
&lt;p&gt;Here’s my typo-laden gitlog for the day to give you an idea of content pace and the type of exercises we worked on:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2017/angular-day2-git-log.png&quot; alt=&quot;Day 2 Gitlog Doesn&amp;#39;t Lie&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;Making-friends-with-RxJS-switchMap-takeUntil-Oh-My&quot;&gt;&lt;a href=&quot;#Making-friends-with-RxJS-switchMap-takeUntil-Oh-My&quot; class=&quot;headerlink&quot; title=&quot;Making friends with RxJS - switchMap(), takeUntil(), Oh My!&quot;&gt;&lt;/a&gt;Making friends with RxJS - switchMap(), takeUntil(), Oh My!&lt;/h2&gt;&lt;p&gt;Christoph and Thomas took us on a tour of the hardcore range of Rx operators that are helpful when working with Observables. Even with marble diagrams, some of these concepts pretty much blew our minds! &lt;/p&gt;
&lt;p&gt;Major. Paradigm. Shift.&lt;/p&gt;
&lt;p&gt;As a last mic drop before the &lt;code&gt;switchMap()&lt;/code&gt; exercise Christoph told us “you’ll work it out” - then pointed it at the lab to learn-by-doing.&lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular Masterclass Day 1 Retro</title>
    <link href="http://blogs.bytecode.com.au/glen/2017/01/09/angular-2-masterclass-day-one.html"/>
    <id>http://blogs.bytecode.com.au/glen/2017/01/09/angular-2-masterclass-day-one.html</id>
    <published>2017-01-09T20:10:07.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Well, yesterday was Day One of the thoughtram <a href="http://thoughtram.io/angular-master-class.html">Angular Masterclass</a> in Sydney and I’m having a ball and learning heaps.</p><p>I thought I’d write up a quick retro to give people an idea of the experience.</p><p>On our first day we build a thing! And that thing did CRUDing operations on RESTful service. And did Databinding and all that Angular-ish goodness. </p><p>In fact, the first day is called their “Jumpstart” day where you cover all the basics to get everyone on the same page.</p><p>This is what I spent the day building:</p><p><img src="/glen/glen/images/2017/thoughtram-contacts-sample.gif" alt="We Built a Thing"></p><h2 id="thoughtram’s-Approach"><a href="#thoughtram’s-Approach" class="headerlink" title="thoughtram’s Approach"></a>thoughtram’s Approach</h2><p>I’ve always been a fan of the <a href="https://www.amazon.com/Training-Back-Room-Aside-Learn-ebook/dp/B0062O7L7S">“Training from the Back of the Room”</a> approach (actually all of Sharon Bowman’s stuff is awesome), and the thoughtram guys definitely train in that school - 20 minute intense  “downloads” of information with Q&amp;A, followed by labs to put it all into practice.</p><p>All their training presentation notes are browser-based and accessed by a participant login on their website. The notes are updated for the life of the course (which is awesome!)</p><p>Ditto for the lab exercises - which are all hosted on Github repos and constantly updated with tweaks.</p><h2 id="Day-One-in-the-Box"><a href="#Day-One-in-the-Box" class="headerlink" title="Day One in the Box"></a>Day One in the Box</h2><p>Being the “Jumpstart” day, you get a taste of everything, starting from a blank “scorched-earth” Angular 2 project containing some supplied CSS and sample data - and building piece by piece on that.</p><p>Based on my Git logs, the day was a solid basics wrap-up:</p><ul><li>The Bootstrapping process (how it works, not just what to type)</li><li>Writing a basic component </li><li>Property Binding</li><li>Basic Directives (<code>*ngFor</code> and <code>*ngIf</code> and friends)</li><li>Component Lifecycyle (eg <code>ngOnInit</code> and what runs when)</li><li>Services and DI (including <code>OpaqueToken</code>, Instance handling and how the DI resolves things)</li><li>Basic Routing from Zero</li><li>Routing with Parameter Passing (<code>routerLink</code> and friends)</li><li>Using Http for basic Observables subscriptions</li><li>Two-Way Databinding in a basic form editor (including how NgModel works as a directive)</li></ul><p>That’s quite a first day. If you’re already using Angular 2 that might sound a little basic, but the great thing about having experienced instructors is that we deep dive all the way along. </p><ul><li>Not sure when component instances get created and how are affected by the the update cycle (in debug and prod modes)? Just ask! </li><li>Keen to know how the router handled instance handling and re-use? Just ask and get a history of how it used it, and how it does now!</li><li>What’s the difference between a template directive and a regular directive? They can talk you through that on the way.</li></ul><p>Covering all those “so I wonder how that actually works?” demystifies a lot of the Angular magic you’d be templated to glaze over and get stuck on down the track. Super valuable. </p><h2 id="And-After-Dark…"><a href="#And-After-Dark…" class="headerlink" title="And After Dark…"></a>And After Dark…</h2><p>The first day was long (9:30 until after 6pm) but it went really fast and the pace intensified as the day went on. </p><p>After hours, Christoph and Thomas took us out to the Opera House Bar for Drinks and Hangout time. This is where you want to be at the end of the first day:</p><p><img src="/glen/glen/images/2017/sydney-opera-house.jpg" alt="View from Opera House Bar Sydney"></p><h2 id="Bring-On-Day-Two"><a href="#Bring-On-Day-Two" class="headerlink" title="Bring On Day Two"></a>Bring On Day Two</h2><p>They team have told us that the intensity ramps up today as we dive into Observables and functional programming. </p><p>Super excited!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Well, yesterday was Day One of the thoughtram &lt;a href=&quot;http://thoughtram.io/angular-master-class.html&quot;&gt;Angular Masterclass&lt;/a&gt; in Sydney and I’m having a ball and learning heaps.&lt;/p&gt;
&lt;p&gt;I thought I’d write up a quick retro to give people an idea of the experience.&lt;/p&gt;
&lt;p&gt;On our first day we build a thing! And that thing did CRUDing operations on RESTful service. And did Databinding and all that Angular-ish goodness. &lt;/p&gt;
&lt;p&gt;In fact, the first day is called their “Jumpstart” day where you cover all the basics to get everyone on the same page.&lt;/p&gt;
&lt;p&gt;This is what I spent the day building:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2017/thoughtram-contacts-sample.gif&quot; alt=&quot;We Built a Thing&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;thoughtram’s-Approach&quot;&gt;&lt;a href=&quot;#thoughtram’s-Approach&quot; class=&quot;headerlink&quot; title=&quot;thoughtram’s Approach&quot;&gt;&lt;/a&gt;thoughtram’s Approach&lt;/h2&gt;&lt;p&gt;I’ve always been a fan of the &lt;a href=&quot;https://www.amazon.com/Training-Back-Room-Aside-Learn-ebook/dp/B0062O7L7S&quot;&gt;“Training from the Back of the Room”&lt;/a&gt; approach (actually all of Sharon Bowman’s stuff is awesome), and the thoughtram guys definitely train in that school - 20 minute intense  “downloads” of information with Q&amp;amp;A, followed by labs to put it all into practice.&lt;/p&gt;
&lt;p&gt;All their training presentation notes are browser-based and accessed by a participant login on their website. The notes are updated for the life of the course (which is awesome!)&lt;/p&gt;
&lt;p&gt;Ditto for the lab exercises - which are all hosted on Github repos and constantly updated with tweaks.&lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>2016 Year In Review</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/12/30/2016-in-review.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/12/30/2016-in-review.html</id>
    <published>2016-12-30T21:15:23.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>I’ve had a cracker this year. It might well have been one of the best years of my life! </p><p>Didn’t write a book. Didn’t have a baby. Didn’t ship a world-beating app. Didn’t speak at any big gigs. Didn’t finish a marathon. Didn’t make a ton of money. Or even have something go viral.</p><p>Nope. None of those things.</p><p>This year I took bold actions toward things that matter to me. </p><p>That is all.</p><p>And that is more than enough.</p><h2 id="Creating-Software"><a href="#Creating-Software" class="headerlink" title="Creating Software."></a>Creating Software.</h2><p>Wrote some great software for clients that makes their lives easier and more productive. Even delivered my own <a href="/glen/2016/11/14/puppymail-v1.html">hobby app</a> to make my own life easier.</p><p><img src="/glen/glen/images/2016/puppymail.png" alt="Puppymail rocks"></p><h2 id="Creating-Video"><a href="#Creating-Video" class="headerlink" title="Creating Video."></a>Creating Video.</h2><p>I had so much fun on my <a href="http://youtube.com/c/freshbytecode">YouTube Channel</a> shooting <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">Learn Angular 2.0 in 21 days</a> and <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmvgZA5pjyljKdmlqtFeU3P">Ship Your Hobby Project in 30 days</a>. That’s a lot of video content, and by the end of it the projection workflow has improved considerably!</p><p><img src="/glen/glen/images/2016/glen-youtube-promo.jpg" alt="Loved Youtube"></p><p>I’m going to be doing a lot more video next year, so make sure you <a href="http://youtube.com/c/freshbytecode">subscribe</a> if you haven’t yet!</p><h2 id="Creating-Blog-Posts"><a href="#Creating-Blog-Posts" class="headerlink" title="Creating Blog Posts."></a>Creating Blog Posts.</h2><p>I love writing. And it was great to get back on the blogging horse this year.</p><p>This is post 46 for this year. That’s almost my busiest blog year on record (only exceeded by 2006 with 47). That was ten years ago when life was a lot simpler!</p><p>I’m really enjoyed the switch to <a href="https://hexo.io/">Hexo</a>, Git and Markdown, and this style of blogging is definitely the minimalist future I’ve been looking for.</p><h2 id="Discovering-Fresh-Community"><a href="#Discovering-Fresh-Community" class="headerlink" title="Discovering Fresh Community."></a>Discovering Fresh Community.</h2><p>I’ve really enjoyed making new friends inside and outside the tech community this year. You really are the sum of the five closest people you hang around - so make sure you’re intentional about those people!</p><p>I’m putting the whole “personal networking” thing front and centre for next year. I’ve learned so many great techniques from <a href="https://fizzle.co/">Fizzle</a> this year that I can’t wait to apply in 2017. </p><p><img src="/glen/glen/images/2016/love-html.png" alt="Loved HTML"></p><h2 id="Rediscoving-the-Web"><a href="#Rediscoving-the-Web" class="headerlink" title="Rediscoving the Web"></a>Rediscoving the Web</h2><p><a href="https://angular.io/">Angular 2</a> and <a href="http://ionic.io/">Ionic 2</a> have really pulled me back into the heart of the WebDev community - and it’s an awesome place to be.</p><p><a href="https://www.typescriptlang.org/">TypeScript</a> is all kinds of wonderful, and I’d happily spend all of 2017 hacking on Angular and Ionic apps in TypeScript. </p><p>In fact, that’s what my diary looks like at the moment.</p><p>So. Very. Pumped.</p><h2 id="Great-Habits"><a href="#Great-Habits" class="headerlink" title="Great Habits"></a>Great Habits</h2><p><a href="https://en.wikiquote.org/wiki/Kent_Beck">Kent Beck</a> said, “I’m not a great programmer; I’m just a good programmer with great habits.”</p><p>This year, I’ve had a really hacked on my own personal habits and have definitely gone next level. </p><p>I’m more disciplined than ever (inside and out), and have worked out some great productivity hacks to be the most effective I’ve been in my life (check out my free <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmvgZA5pjyljKdmlqtFeU3P">Ship Your Hobby Project in 30 days</a> for an insight).</p><h2 id="And-2017-looks-even-more-awesome…"><a href="#And-2017-looks-even-more-awesome…" class="headerlink" title="And 2017 looks even more awesome…"></a>And 2017 looks even more awesome…</h2><p>So many great projects scheduled for 2017. Can’t wait to get started!</p><p>Thanks for hanging out!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;I’ve had a cracker this year. It might well have been one of the best years of my life! &lt;/p&gt;
&lt;p&gt;Didn’t write a book. Didn’t have a baby. Didn’t ship a world-beating app. Didn’t speak at any big gigs. Didn’t finish a marathon. Didn’t make a ton of money. Or even have something go viral.&lt;/p&gt;
&lt;p&gt;Nope. None of those things.&lt;/p&gt;
&lt;p&gt;This year I took bold actions toward things that matter to me. &lt;/p&gt;
&lt;p&gt;That is all.&lt;/p&gt;
&lt;p&gt;And that is more than enough.&lt;/p&gt;
&lt;h2 id=&quot;Creating-Software&quot;&gt;&lt;a href=&quot;#Creating-Software&quot; class=&quot;headerlink&quot; title=&quot;Creating Software.&quot;&gt;&lt;/a&gt;Creating Software.&lt;/h2&gt;&lt;p&gt;Wrote some great software for clients that makes their lives easier and more productive. Even delivered my own &lt;a href=&quot;/glen/2016/11/14/puppymail-v1.html&quot;&gt;hobby app&lt;/a&gt; to make my own life easier.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/puppymail.png&quot; alt=&quot;Puppymail rocks&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;Creating-Video&quot;&gt;&lt;a href=&quot;#Creating-Video&quot; class=&quot;headerlink&quot; title=&quot;Creating Video.&quot;&gt;&lt;/a&gt;Creating Video.&lt;/h2&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Configuring Yarn to use Nexus</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/12/23/nexus-and-yarn.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/12/23/nexus-and-yarn.html</id>
    <published>2016-12-23T20:10:17.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>I’ve been a huge fan of <a href="http://www.sonatype.org/nexus/">Nexus</a> for inhouse proxying of Maven artefacts for years. I’ve used it at heaps of government sites where it was a hassle to get internet access through content proxies, and it’s been a life saver. But you might not know that Nexus is also awesome for proxying NPM, Bower and even Docker images. </p><p>If you need to configure your local npm to point to Nexus, there’s <a href="https://books.sonatype.com/nexus-book/reference/npm-configuring.html">awesome docs on that</a>.</p><p><img src="/glen/glen/images/2016/yarn.jpg" alt="Yarn is npm with win"></p><p>However, I’ve now started experimenting with <a href="https://yarnpkg.com/">yarn</a>, <a href="https://code.facebook.com/posts/1840075619545360">Facebook’s</a> drop in replacement for npm (but quite a bit faster!), and so was naturally wondering how to configure it to use my local Nexus proxy.</p><p>Turns out it’s simply a matter of: </p><pre><code>yarn config set registry http://localhost:8081/repository/npm-central/</code></pre><p>And you’re off and running. I thought I would write it down so I can google it later!</p><p>You can confirm that life is great, but tailing your <code>/nexus/log/request.log</code> and watch the traffic flowing (or try a <code>yarn install --verbose</code> and sit back!).</p><p>Have fun!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;I’ve been a huge fan of &lt;a href=&quot;http://www.sonatype.org/nexus/&quot;&gt;Nexus&lt;/a&gt; for inhouse proxying of Maven artefacts for years. I’ve used it at heaps of government sites where it was a hassle to get internet access through content proxies, and it’s been a life saver. But you might not know that Nexus is also awesome for proxying NPM, Bower and even Docker images. &lt;/p&gt;
&lt;p&gt;If you need to configure your local npm to point to Nexus, there’s &lt;a href=&quot;https://books.sonatype.com/nexus-book/reference/npm-configuring.html&quot;&gt;awesome docs on that&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/yarn.jpg&quot; alt=&quot;Yarn is npm with win&quot;&gt;&lt;/p&gt;
&lt;p&gt;However, I’ve now started experimenting with &lt;a href=&quot;https://yarnpkg.com/&quot;&gt;yarn&lt;/a&gt;, &lt;a href=&quot;https://code.facebook.com/posts/1840075619545360&quot;&gt;Facebook’s&lt;/a&gt; drop in replacement for npm (but quite a bit faster!), and so was naturally wondering how to configure it to use my local Nexus proxy.&lt;/p&gt;
&lt;p&gt;Turns out it’s simply a matter of: &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;yarn config set registry http://localhost:8081/repository/npm-central/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And you’re off and running. I thought I would write it down so I can google it later!&lt;/p&gt;
&lt;p&gt;You can confirm that life is great, but tailing your &lt;code&gt;/nexus/log/request.log&lt;/code&gt; and watch the traffic flowing (or try a &lt;code&gt;yarn install --verbose&lt;/code&gt; and sit back!).&lt;/p&gt;
&lt;p&gt;Have fun!&lt;/p&gt;
</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Painless Push Notifications with Pushover</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/12/22/painless-push-with-pushover.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/12/22/painless-push-with-pushover.html</id>
    <published>2016-12-22T20:09:17.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>I have to say that Push Notifications are just super cool. </p><p>Think how cool would it be to make your Mobile ding with a custom sound every time a really important event happened in one of your systems? </p><ul><li>Just sold another one of your apps? Cash Register Ding.</li><li>Just crashed your production server? Death Spiral ding.</li><li>Just crossed an 100k subs?  Happy Sound ding.</li></ul><p>Way cooler than SMS :-).</p><p>And it turns out adding such features into your app is totally trivial thanks to the good folk at Pushover.net. And today I’m going to show you how!</p><h2 id="Enter-Pushover"><a href="#Enter-Pushover" class="headerlink" title="Enter Pushover"></a>Enter Pushover</h2><p><a href="https://pushover.net/">Pushover</a> is a web service (and suite of platform specific mobile apps for Android, IoS and the Browser) that lets you easily push Notifications to all (or one) of your registered devices whenever you would like.</p><p>It’s a one-off $5 subscription cost per platform, then you’re free to send up to 7500 notifications month forever. That’s a lot of events! </p><p><img src="/glen/glen/images/2016/pushover.jpg" alt="Pushover.net is win"></p><h2 id="Integrating-with-Ionic-2-or-Angular-2-or-whatever"><a href="#Integrating-with-Ionic-2-or-Angular-2-or-whatever" class="headerlink" title="Integrating with Ionic 2 or Angular 2 (or whatever)"></a>Integrating with Ionic 2 or Angular 2 (or whatever)</h2><p>Integrating the <a href="https://pushover.net/api">Pushover API</a> into your app is a snack. There are node modules, and other third party API libs (Java, C#, Python and all the other good gear) to use out of the gate, but the API is simple form POST to an endpoint, so rolling your own is no big deal either. I’ll show you how.</p><p>In Angular 2, I’d create a <code>pushover.service.ts</code> file to host my service, and drag in my keys and endpoints:</p><pre><code>@Injectable()export class PushoverService &#123;    private PUSHOVER_ENDPOINT=&#39;https://api.pushover.net/1/messages.json&#39;;    private PUSHOVER_TOKEN=&#39;your-magic-token-here&#39;;    private PUSHOVER_USER_KEY=&#39;your-user-key-here&#39;;    constructor(private http : Http) &#123; &#125;&#125;</code></pre><p>And with my shell class in place, there’s just the small matter of performing that actual form POST and getting those notifications rolling in:</p><pre><code>sendNotification(title : string, body : string) : Observable&lt;Object&gt;&#123;    let pushoverMessage = &#123;        token : this.PUSHOVER_TOKEN,        user: this.PUSHOVER_USER_KEY,        title: title,        message: body    &#125;;    let options = &#123;&#125; as RequestOptionsArgs;    options.headers = new Headers(&#123; &#39;Content-Type&#39;: &#39;application/x-www-form-urlencoded&#39; &#125;);    let pushoverStr = this.mapToFormData(pushoverMessage);    console.log(`Pushing message $&#123;pushoverStr&#125;`);    return this.http.post(this.PUSHOVER_ENDPOINT, pushoverStr, options).map( resp =&gt; &#123;    if (resp)        if (resp.status == 200) &#123;            return resp.json()        &#125; else &#123;            throw resp;        &#125;    &#125;).catch((err, other) =&gt; &#123;        console.log(&quot;Trouble in the land of POST&quot;, err);        return Observable.throw(err);    &#125;);&#125;</code></pre><p>The only other magic I needed was a way to format my data into an old school form POST. There’s probably a better way in npm to do this stuff, but here’s my heavy hammer approach:</p><pre><code>public mapToFormData(map: Object): string &#123;    let formData = &#39;&#39;;    for (var key in map) &#123;        if (formData)            formData += &#39;&amp;&#39;;        let eKey = encodeURIComponent(key);        let eValue = encodeURIComponent(map[key]);        formData += `$&#123;eKey&#125;=$&#123;eValue&#125;`;    &#125;    return formData;&#125;</code></pre><p>And will all the code happening, it’s a matter of calling it from my login form:</p><pre><code>this.notificationsService.sendNotification(`Successful login for $&#123;as.auth.email&#125;`, &quot;With all kinds of winning&quot;).    subscribe( value =&gt; &#123; console.log(&quot;Winning&quot;; &#125;,    err =&gt; &#123; console.log(&quot;Observable threw&quot;, err); &#125;)</code></pre><p>And then sit back and enjoy the greatness:</p><p><img src="/glen/glen/images/2016/pushover-notification.jpg" alt="Enjoy the Greatness"></p><p>Having so much fun with this stuff. Thanks <a href="https://pushover.net/">Pushover.net</a>!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;I have to say that Push Notifications are just super cool. &lt;/p&gt;
&lt;p&gt;Think how cool would it be to make your Mobile ding with a custom sound every time a really important event happened in one of your systems? &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Just sold another one of your apps? Cash Register Ding.&lt;/li&gt;
&lt;li&gt;Just crashed your production server? Death Spiral ding.&lt;/li&gt;
&lt;li&gt;Just crossed an 100k subs?  Happy Sound ding.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Way cooler than SMS :-).&lt;/p&gt;
&lt;p&gt;And it turns out adding such features into your app is totally trivial thanks to the good folk at Pushover.net. And today I’m going to show you how!&lt;/p&gt;
&lt;h2 id=&quot;Enter-Pushover&quot;&gt;&lt;a href=&quot;#Enter-Pushover&quot; class=&quot;headerlink&quot; title=&quot;Enter Pushover&quot;&gt;&lt;/a&gt;Enter Pushover&lt;/h2&gt;&lt;p&gt;&lt;a href=&quot;https://pushover.net/&quot;&gt;Pushover&lt;/a&gt; is a web service (and suite of platform specific mobile apps for Android, IoS and the Browser) that lets you easily push Notifications to all (or one) of your registered devices whenever you would like.&lt;/p&gt;
&lt;p&gt;It’s a one-off $5 subscription cost per platform, then you’re free to send up to 7500 notifications month forever. That’s a lot of events! &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/pushover.jpg&quot; alt=&quot;Pushover.net is win&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;Integrating-with-Ionic-2-or-Angular-2-or-whatever&quot;&gt;&lt;a href=&quot;#Integrating-with-Ionic-2-or-Angular-2-or-whatever&quot; class=&quot;headerlink&quot; title=&quot;Integrating with Ionic 2 or Angular 2 (or whatever)&quot;&gt;&lt;/a&gt;Integrating with Ionic 2 or Angular 2 (or whatever)&lt;/h2&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
    <category term="Ionic" scheme="http://blogs.bytecode.com.au/glen/tags/Ionic/"/>
    
  </entry>
  
  <entry>
    <title>The Thoughtram guys are coming to Sydney!</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/12/21/angular-2-masterclass-sydney.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/12/21/angular-2-masterclass-sydney.html</id>
    <published>2016-12-21T02:06:38.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>And I’m so there!</p><p>It’s no surprise to any of my friends that I’ve doubled-down hard on Angular 2 this year. I built <a href="/glen/2016/11/14/puppymail-v1.html">PuppyMail</a> to learn all about serverless Angular apps with Firebase, taught a <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">21 days of Angular</a> YouTube course, spoke at a <a href="https://www.meetup.com/Canberra-Java-User-Group/events/233297712/">Meetup on Angular 2 for Java Devs</a>, and have lately been diving in hard on <a href="http://ionic.io/">Ionic 2</a> (think of Ionic 2 as Angular 2 for Hybrid Mobile apps).</p><p><img src="/glen/glen/images/2016/glen-youtube-promo.jpg" alt="Love Teaching on YouTube"></p><p>But there’s so much more to learn! I’m only scratching the surface of Observables, Forms, Unit Testing, DI scoping and lots more!</p><p>As you may know, I’m a massive fan of Hobby Projects for levelling up. I even did an eight-part <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmvgZA5pjyljKdmlqtFeU3P">YouTube Series</a> on Shipping Your Hobby Project in 30 days. But I’m also a massive fan of osmosis in community. Of hanging out with guys and girls that are further along the road than you, and leveraging off that talent and experience.</p><p>So when I heard the legends from <a href="http://thoughtram.io/">Thoughtram</a> are coming to <a href="https://www.eventbrite.de/e/angular-2-master-class-sydney-tickets-28884003833">Sydney</a> to teach their <a href="http://thoughtram.io/angular-master-class.html">Angular 2 Masterclass</a> I was super pumped! These guys are committers on Angular 2, Angular Material, and prolific bloggers - you’re probably read some of their (hardcore) blog posts while researching Angular 2 stuff. </p><p>This is going to be an awesome opportunity from best-in-class Angular 2 folk in our own backyard - from Jan 9-11. Can’t wait to hang out with them! (and not sure why this is the first I heard of it - but now you know too!).</p><p><img src="/glen/glen/images/2016/thoughtram-angular-masterclass.jpg" alt="Thoughtram Angular 2 Master Class"></p><p>If you live in AU&#x2F;NZ and are keen for a Sydney trip, why not come and hang out! There are <a href="https://www.eventbrite.de/e/angular-2-master-class-sydney-tickets-28884003833">still tickets</a>!</p><h2 id="Where-to-stay"><a href="#Where-to-stay" class="headerlink" title="Where to stay?"></a>Where to stay?</h2><p>Sorting out accommodation and transport is always a big hassle when travelling for training. </p><p>Here’s my $0.02 on what I’ve found out so far.</p><p>After a fair bit of research, I’m going to be staying at <a href="https://www.wotif.com/Sydney-Hotels-The-Tank-Stream.h11718621.Hotel-Information?semcid=wotif-au.ub.Google.search.hotel&kword=e.%7Ctank%20stream%20hotel%7C.403.11784.369632.2583451.165215072869&epi=a65c5611-b6b8-4d61-9870-58a2df583741&gclid=Cj0KEQiAyuPCBRCimuayhb3qqvwBEiQAgz62kXdhs6-DocJM_EH6ZJCrVJzi2J3cHgFEVzQ1Ul5gsqUaAswF8P8HAQ#chkin=09%2F01%2F2017&chkout=11%2F01%2F2017&daysInFuture=&stayLength=&adults=2&children=0&ts=1482286678284">The Tank Stream</a> Hotel which is just around the corner from the training venue <a href="http://tankstreamlabs.com/">Tank Stream Labs</a>. Pretty cool rooms from $160&#x2F;night - which is pretty cheap for Sydney City.</p><p>It’s also accessible from Wynyard station, so it’s easy to get there from the Airport (and get home when we’re done)</p><p><img src="/glen/glen/images/2016/tank-stream-hotel.jpg" alt="Tank Stream Hotel Sydney"></p><h2 id="And-after-that"><a href="#And-after-that" class="headerlink" title="And after that?"></a>And after that?</h2><p>I already have a few Angular 2 and Ionic 2 projects banking up for 2017 - both commercial consulting and startup gigs, so this is the absolute perfect kickstart. </p><p>Hope to see you there! </p><p>And will report back on how it goes…</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;And I’m so there!&lt;/p&gt;
&lt;p&gt;It’s no surprise to any of my friends that I’ve doubled-down hard on Angular 2 this year. I built &lt;a href=&quot;/glen/2016/11/14/puppymail-v1.html&quot;&gt;PuppyMail&lt;/a&gt; to learn all about serverless Angular apps with Firebase, taught a &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;21 days of Angular&lt;/a&gt; YouTube course, spoke at a &lt;a href=&quot;https://www.meetup.com/Canberra-Java-User-Group/events/233297712/&quot;&gt;Meetup on Angular 2 for Java Devs&lt;/a&gt;, and have lately been diving in hard on &lt;a href=&quot;http://ionic.io/&quot;&gt;Ionic 2&lt;/a&gt; (think of Ionic 2 as Angular 2 for Hybrid Mobile apps).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/glen-youtube-promo.jpg&quot; alt=&quot;Love Teaching on YouTube&quot;&gt;&lt;/p&gt;
&lt;p&gt;But there’s so much more to learn! I’m only scratching the surface of Observables, Forms, Unit Testing, DI scoping and lots more!&lt;/p&gt;
&lt;p&gt;As you may know, I’m a massive fan of Hobby Projects for levelling up. I even did an eight-part &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmvgZA5pjyljKdmlqtFeU3P&quot;&gt;YouTube Series&lt;/a&gt; on Shipping Your Hobby Project in 30 days. But I’m also a massive fan of osmosis in community. Of hanging out with guys and girls that are further along the road than you, and leveraging off that talent and experience.&lt;/p&gt;
&lt;p&gt;So when I heard the legends from &lt;a href=&quot;http://thoughtram.io/&quot;&gt;Thoughtram&lt;/a&gt; are coming to &lt;a href=&quot;https://www.eventbrite.de/e/angular-2-master-class-sydney-tickets-28884003833&quot;&gt;Sydney&lt;/a&gt; to teach their &lt;a href=&quot;http://thoughtram.io/angular-master-class.html&quot;&gt;Angular 2 Masterclass&lt;/a&gt; I was super pumped! These guys are committers on Angular 2, Angular Material, and prolific bloggers - you’re probably read some of their (hardcore) blog posts while researching Angular 2 stuff. &lt;/p&gt;
&lt;p&gt;This is going to be an awesome opportunity from best-in-class Angular 2 folk in our own backyard - from Jan 9-11. Can’t wait to hang out with them! (and not sure why this is the first I heard of it - but now you know too!).&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/thoughtram-angular-masterclass.jpg&quot; alt=&quot;Thoughtram Angular 2 Master Class&quot;&gt;&lt;/p&gt;
&lt;p&gt;If you live in AU&amp;#x2F;NZ and are keen for a Sydney trip, why not come and hang out! There are &lt;a href=&quot;https://www.eventbrite.de/e/angular-2-master-class-sydney-tickets-28884003833&quot;&gt;still tickets&lt;/a&gt;!&lt;/p&gt;
&lt;h2 id=&quot;Where-to-stay&quot;&gt;&lt;a href=&quot;#Where-to-stay&quot; class=&quot;headerlink&quot; title=&quot;Where to stay?&quot;&gt;&lt;/a&gt;Where to stay?&lt;/h2&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Lessons from my first Angular2 app</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/11/13/puppymail-v1.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/11/13/puppymail-v1.html</id>
    <published>2016-11-13T23:47:00.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>I’m totally convinced that the best way to learn anything is through having a hobby project. I’m so convinced about that, that I created a <a href="/glen/2016/10/13/ship-your-side-project.html">free 8-lesson YouTube course</a> around that topic!</p><p>Well I’ve just finished “walking the talk” of that course - a 31 day streak of moving a hobby project forward from zero to basic features complete:</p><p><img src="/glen/glen/images/2016/31-day-streak.png" alt="31 Day Streak To Get it Home"></p><h2 id="Learning-Goals"><a href="#Learning-Goals" class="headerlink" title="Learning Goals"></a>Learning Goals</h2><p>I developed a small Angular 2 application, with a few very simple goals:</p><ul><li>Learn about using <a href="https://firebase.google.com/">Firebase</a> for Backend Storage (essentially a serverless* application)</li><li>Create an app I actually need. In my case, that was an app to make use of my <a href="http://www.getpocket.com/">Pocket</a> links when generating eNewsletter (in my case the <a href="http://www.motivatedprogrammer.com/">Motivated Programmer</a> newsletter. You should sign up!)</li><li>Build something substantial in Angular 2 and get a feel for whether I’d like it on larger apps.</li></ul><p>So I birthed <a href="http://blogs.bytecode.com.au/projects/puppymail/">“PuppyMail”</a> to scratch that itch.</p><p><img src="/glen/glen/images/2016/puppymail.png" alt="The Rise of PuppyMail"></p><p>Well PuppyMail delivered in spades on those three objectives. With the TL&#x2F;DR being:</p><ul><li>Firebase is all kinds of awesome. Particularly when coupled with <a href="https://github.com/angular/angularfire2">AngularFire2</a>.</li><li>I could deliver “Cradle to Grave” on all the basic features that I wanted in this app in 29 hours - or basically a month of hobby hacking every day. </li><li>Angular 2 all the things! I love this framework <em>so</em> much.</li></ul><h2 id="Show-me-the-screenshots"><a href="#Show-me-the-screenshots" class="headerlink" title="Show me the screenshots!"></a>Show me the screenshots!</h2><p>Ladies and Gentleman, I give you <a href="http://blogs.bytecode.com.au/projects/puppymail/">PuppyMail</a>:</p><p><img src="/glen/glen/images/2016/puppymail-dashboard.png" alt="The PuppyMail Dashboard"></p><p>And I thought I would go all out with a landing page to (with links to source, etc).</p><p><img src="/glen/glen/images/2016/puppymail-landing.png" alt="The Landing Page"></p><h2 id="What-did-you-learn-along-the-way"><a href="#What-did-you-learn-along-the-way" class="headerlink" title="What did you learn along the way?"></a>What did you learn along the way?</h2><p>Yes. Well. There were quite a few side tracks in those 31 days. But all wonderful learning experiences none the less.</p><p>A few things really did prove trickier than I anticipated.</p><h3 id="1-GetPocket-doesn’t-support-CORS"><a href="#1-GetPocket-doesn’t-support-CORS" class="headerlink" title="1. GetPocket doesn’t support CORS"></a>1. GetPocket doesn’t support CORS</h3><p>First “crash and burn” moment for me was lack of CORS support on the GetPocket API. </p><p>That meant the standard http angular component would die in the browser when doing the cross-origin calls. This lead to a tiny bit of glue in a node proxy which I called puppymail-server. Under the covers, it just uses <a href="https://github.com/villadora/express-http-proxy">express-http-proxy</a> to do all the heavy lifting.</p><h3 id="2-Custom-Firebase-tokens"><a href="#2-Custom-Firebase-tokens" class="headerlink" title="2. Custom Firebase tokens"></a>2. Custom Firebase tokens</h3><p>I needed to generate Custom tokens for Firebase logins (since I wanted the user to be able to use their GetPocket creds as auth to the Database)</p><p>This was actually a blessing, since I already had the proxy server doing all the Pocket oAuth proxying, so it was easy to inject a custom Firebase token on the way back from a successful oAuth. </p><p>The Database Auth rules on Firebase are just fantastic. I can lock down sections of the Db to just the user that creates them. So very painless!</p><h3 id="3-PrimeNG-is-so-productive"><a href="#3-PrimeNG-is-so-productive" class="headerlink" title="3. PrimeNG is so productive"></a>3. PrimeNG is so productive</h3><p>Paginated lists turned out to be trivial. Just throw in a PrimeNG <a href="http://www.primefaces.org/primeng/#/datalist">DataList component</a>, point it at your array of objects, and you’re good to go. Rince and repeat for <a href="http://www.primefaces.org/primeng/#/orderlist">OrderList</a> if you need to sort that list. Throw in a few <a href="http://www.primefaces.org/primeng/#/growl">Growl notifications</a>, a couple of <a href="http://www.primefaces.org/primeng/#/splitbutton">SplitButtons</a>, and a pinch of <a href="http://www.primefaces.org/primeng/#/dialog">Dialog</a> action and you’re cooking.</p><p>I will definitely be recommending <a href="http://www.primefaces.org/primeng/#/">PrimeNG</a> to enterprise clients as a great way to standardise the app experience.</p><h3 id="4-SemanticUI-makes-so-much-sense"><a href="#4-SemanticUI-makes-so-much-sense" class="headerlink" title="4. SemanticUI makes so much sense"></a>4. SemanticUI makes so much sense</h3><p>I’ve used <a href="http://getbootstrap.com/">Bootstrap</a> a lot in the past, and <a href="http://semantic-ui.com/">SemanticUI</a> really takes ideas to a whole new level of usability. The whole “semantic-ness” is just so readable!  I love creating a <code>&lt;div class=&#39;stackable two column grid&#39;&gt;</code>!</p><p>I need to get deeper in SemanticUI, and fortunately <a href="http://semantic-ui.com/">the docs</a> are just awesome.</p><h3 id="5-Deep-Linking-and-Nginx"><a href="#5-Deep-Linking-and-Nginx" class="headerlink" title="5. Deep Linking and Nginx"></a>5. Deep Linking and Nginx</h3><p>This one really caught me off guard in deployment. Nginx kept throwing 404s when deep linking into the app using html5 style URLs. </p><p>You’d end up with requests like: &#x2F;puppymail&#x2F;login&#x2F;backFromPocket which you’d hope would route to the LoginController, but end up 404’ing as Nginx tried to resolve that to a real file. Apparently there are <a href="http://stackoverflow.com/questions/31415052/angular-2-0-router-not-working-on-reloading-the-browser">serverside fixes</a> which map all 404’s back to <code>index.html</code> to support this. That’s on my list, but a quick workaround is using a <code>HashMappingStrategy</code> in the router on the client side. </p><p>This means you end up “hashy” style links like <code>/puppymail/#/login/backFromPocket</code>, but that doesn’t worry me for now - especially since it was a one-line change to my Angular module to:</p><pre><code>  imports: [RouterModule.forRoot(routes, &#123; useHash: true &#125;)],</code></pre><p>And I was done!</p><h3 id="6-through-1000"><a href="#6-through-1000" class="headerlink" title="6. through 1000."></a>6. through 1000.</h3><p>There were tons of other stuff I learned along the way about Angular 2 - particularly in creating re-usable components that shared data across the app. Still plenty to learn about Observables, RxJS and error handling. But the pieces are coming together for me. </p><p>I just can’t believe how fast the thing runs too! Just awesome!</p><p>Can’t wait for my next hobby project. I can feel some <a href="http://ionic.io/2">Ionic 2</a> mobile app action coming on to channel my Angular passion into the mobile space.  </p><p>And in the meantime, if you are a GetPocket user, have a play with <a href="http://blogs.bytecode.com.au/projects/puppymail/">PuppyMail</a>, or checkout the <a href="https://github.com/glenasmith/puppymail">source code</a>, or just sign up to the <a href="http://www.motivatedprogrammer.com/">Motivated Programmer Newsletter</a>.</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;I’m totally convinced that the best way to learn anything is through having a hobby project. I’m so convinced about that, that I created a &lt;a href=&quot;/glen/2016/10/13/ship-your-side-project.html&quot;&gt;free 8-lesson YouTube course&lt;/a&gt; around that topic!&lt;/p&gt;
&lt;p&gt;Well I’ve just finished “walking the talk” of that course - a 31 day streak of moving a hobby project forward from zero to basic features complete:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/31-day-streak.png&quot; alt=&quot;31 Day Streak To Get it Home&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;Learning-Goals&quot;&gt;&lt;a href=&quot;#Learning-Goals&quot; class=&quot;headerlink&quot; title=&quot;Learning Goals&quot;&gt;&lt;/a&gt;Learning Goals&lt;/h2&gt;&lt;p&gt;I developed a small Angular 2 application, with a few very simple goals:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Learn about using &lt;a href=&quot;https://firebase.google.com/&quot;&gt;Firebase&lt;/a&gt; for Backend Storage (essentially a serverless* application)&lt;/li&gt;
&lt;li&gt;Create an app I actually need. In my case, that was an app to make use of my &lt;a href=&quot;http://www.getpocket.com/&quot;&gt;Pocket&lt;/a&gt; links when generating eNewsletter (in my case the &lt;a href=&quot;http://www.motivatedprogrammer.com/&quot;&gt;Motivated Programmer&lt;/a&gt; newsletter. You should sign up!)&lt;/li&gt;
&lt;li&gt;Build something substantial in Angular 2 and get a feel for whether I’d like it on larger apps.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So I birthed &lt;a href=&quot;http://blogs.bytecode.com.au/projects/puppymail/&quot;&gt;“PuppyMail”&lt;/a&gt; to scratch that itch.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/puppymail.png&quot; alt=&quot;The Rise of PuppyMail&quot;&gt;&lt;/p&gt;
&lt;p&gt;Well PuppyMail delivered in spades on those three objectives. With the TL&amp;#x2F;DR being:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Firebase is all kinds of awesome. Particularly when coupled with &lt;a href=&quot;https://github.com/angular/angularfire2&quot;&gt;AngularFire2&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;I could deliver “Cradle to Grave” on all the basic features that I wanted in this app in 29 hours - or basically a month of hobby hacking every day. &lt;/li&gt;
&lt;li&gt;Angular 2 all the things! I love this framework &lt;em&gt;so&lt;/em&gt; much.&lt;/li&gt;
&lt;/ul&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Setting up PrimeNG with the Angular CLI</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/10/27/primeng-with-angular-cli.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/10/27/primeng-with-angular-cli.html</id>
    <published>2016-10-27T03:11:05.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>I loved hacking on <a href="http://primefaces.org/">Primefaces</a> when I was working fulltime in JSF2. In fact, the whole component-based development thing is really what attracted me to Angular 2. </p><p>But since switching, I’ve really been looking for a solid component library to get work done. I’ve been having great success with <a href="http://semantic-ui.com/">Semantic UI</a> for styling, but nothing beats being able to bind a paginated list to an Array<PocketPost> and getting all the strong typing!</p><p>Enter <a href="http://www.primefaces.org/primeng/">PrimeNG</a> aka Primefaces for Angular 2! This library brings all the stunning engineering and pragmatism from Primefaces to the Angular 2 domain. And it totally rocks!</p><p>Here’s that list of my <code>PocketEntries</code> rendering in a PrimeNG paginated <a href="http://www.primefaces.org/primeng/#/orderlist">OrderList</a>. In the words of Kanye, “Enjoy the greatness!”</p><p><img src="/glen/glen/images/2016/primeng-paginated-list.jpg" alt="PrimeNG OrderList in Action"></p><p>And there are only a few lines of code backing all that magic. </p><p>But the $1M question is, “How do you integrate it with the <a href="https://cli.angular.io/">Angular CLI</a>?”</p><p>Turns out that it’s a snack…</p><h2 id="Integrating-PrimeNG-with-Angular-CLI"><a href="#Integrating-PrimeNG-with-Angular-CLI" class="headerlink" title="Integrating PrimeNG with Angular CLI"></a>Integrating PrimeNG with Angular CLI</h2><p>I’m sure the existing <a href="http://www.primefaces.org/primeng/#/setup">setup page</a> will cover all this at some stage. But until then, here’s the steps you’ll need to use PrimeNG with Angular CLI.</p><p>First, install the dependency, and save it to your project…</p><pre><code>npm install primeng --savenpm install font-awesome --save</code></pre><p>Once that is installed, you’ll have a <code>./node_modules/primeng/</code> directory (and a <code>./node_modules/font-awesome/</code> directory). Edit the <code>angular-cli.json</code> file in your root directory to include the PrimeNG style tags you’ll need:</p><pre><code>&quot;styles&quot;: [    &quot;styles.css&quot;,    &quot;../node_modules/font-awesome/css/font-awesome.css&quot;,    &quot;../node_modules/primeng/resources/themes/omega/theme.css&quot; , // or whatever theme you prefer    &quot;../node_modules/primeng/resources/primeng.css&quot;],</code></pre><p>You’ll need font-awesome for some of the icon glyphs, so I added it to the styles above.</p><p>With the styles in place, it’s time to drag in the modules you’ll need to update your <code>app.module.ts</code> to load the modules of the components you need. </p><p>You’ll find the name of the module you need to load on the Documentation tab of the component you want to use on the PrimeNG website. For example, on the <a href="http://www.primefaces.org/primeng/#/orderlist">OrderList</a> page, the Documentation tab says:</p><pre><code>import &#123;OrderListModule&#125; from &#39;primeng/primeng&#39;;</code></pre><p>So you’ll need to add that line to the top of your <code>app.module.ts</code>. Then finally, include the component in your <code>imports:</code> section of <code>app.module.ts</code> towards the bottom of the file (which makes sure the <code>p-dataList</code> tag becomes active in your markup. So, your <code>app.module.ts</code> will have something like:</p><pre><code>imports: [    BrowserModule,    FormsModule,    HttpModule,    OrderListModule, // this line brings the magic of p-dataList to your markup!  ]</code></pre><p>With those bits in play, you can start using the <code>p-dataList</code> tag in your actual markup:</p><pre><code>&lt;p-dataList [value]=&quot;entries&quot; [paginator]=&quot;true&quot; [rows]=&quot;5&quot; [paginatorPosition]=&quot;both&quot;&gt;</code></pre><p>In my case <code>entries</code> is an <code>Array&lt;PocketEntry&gt;</code> property on my controller, which I can iterate over to output each Pocket link entry. </p><p>To make the iteration happen, inside the <code>p-dataList</code> markup you specify a <code>template</code> directive which gets output for each iteration of my <code>entries</code> (in a very similar style to good ‘ol Primefaces). </p><p>I want to call each iteration <code>entry</code>, so the line I need is:</p><pre><code>&lt;template let-entry&gt;</code></pre><p>Then I’m free to start referencing that <code>entry</code> variable as I choose..</p><pre><code>    &lt;div class=&quot;content&quot;&gt;        &lt;a class=&quot;header&quot;&gt;&#123;&#123;entry.resolved_title&#125;&#125;&lt;/a&gt;        &lt;div class=&quot;meta&quot;&gt;            &lt;span class=&quot;cinema&quot;&gt;&lt;a [href]=&#39;entry.resolved_url&#39;&gt;&#123;&#123;entry.resolved_url&#125;&#125;&lt;/a&gt;&lt;/span&gt;        &lt;/div&gt;        &lt;div class=&quot;description&quot;&gt;            &lt;p&gt;&#123;&#123;entry.excerpt&#125;&#125;&lt;/p&gt;        &lt;/div&gt;    &lt;/div&gt; &lt;!-- etc... --&gt;</code></pre><p>Super productive! </p><p>It’s been amazing to see the <a href="http://www.primefaces.org/primeng">PrimeNG</a> library take shape - there are already <em>dozens</em> of components in place - all with the super high engineering standards that the Prime team deliver (check out their <a href="https://github.com/primefaces/primeng/">source code</a> and enjoy the greatness!)</p><p>Awesome work Prime!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;I loved hacking on &lt;a href=&quot;http://primefaces.org/&quot;&gt;Primefaces&lt;/a&gt; when I was working fulltime in JSF2. In fact, the whole component-based development thing is really what attracted me to Angular 2. &lt;/p&gt;
&lt;p&gt;But since switching, I’ve really been looking for a solid component library to get work done. I’ve been having great success with &lt;a href=&quot;http://semantic-ui.com/&quot;&gt;Semantic UI&lt;/a&gt; for styling, but nothing beats being able to bind a paginated list to an Array&lt;pocketpost&gt; and getting all the strong typing!&lt;/pocketpost&gt;&lt;/p&gt;
&lt;p&gt;Enter &lt;a href=&quot;http://www.primefaces.org/primeng/&quot;&gt;PrimeNG&lt;/a&gt; aka Primefaces for Angular 2! This library brings all the stunning engineering and pragmatism from Primefaces to the Angular 2 domain. And it totally rocks!&lt;/p&gt;
&lt;p&gt;Here’s that list of my &lt;code&gt;PocketEntries&lt;/code&gt; rendering in a PrimeNG paginated &lt;a href=&quot;http://www.primefaces.org/primeng/#/orderlist&quot;&gt;OrderList&lt;/a&gt;. In the words of Kanye, “Enjoy the greatness!”&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/primeng-paginated-list.jpg&quot; alt=&quot;PrimeNG OrderList in Action&quot;&gt;&lt;/p&gt;
&lt;p&gt;And there are only a few lines of code backing all that magic. &lt;/p&gt;
&lt;p&gt;But the $1M question is, “How do you integrate it with the &lt;a href=&quot;https://cli.angular.io/&quot;&gt;Angular CLI&lt;/a&gt;?”&lt;/p&gt;
&lt;p&gt;Turns out that it’s a snack…&lt;/p&gt;
&lt;h2 id=&quot;Integrating-PrimeNG-with-Angular-CLI&quot;&gt;&lt;a href=&quot;#Integrating-PrimeNG-with-Angular-CLI&quot; class=&quot;headerlink&quot; title=&quot;Integrating PrimeNG with Angular CLI&quot;&gt;&lt;/a&gt;Integrating PrimeNG with Angular CLI&lt;/h2&gt;&lt;p&gt;I’m sure the existing &lt;a href=&quot;http://www.primefaces.org/primeng/#/setup&quot;&gt;setup page&lt;/a&gt; will cover all this at some stage. But until then, here’s the steps you’ll need to use PrimeNG with Angular CLI.&lt;/p&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Pocket Casts is WIN for Podcasts</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/10/20/pocketcasts-is-win-for-podcasts.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/10/20/pocketcasts-is-win-for-podcasts.html</id>
    <published>2016-10-20T22:58:35.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Now that I’ve established some routines around my exercise habits, I’m finding that I’m listening to a lot more podcasts. And there is some epic free content out there these days (more on that later).</p><h2 id="A-short-rant-about-Pocket-Casts-awesomeness"><a href="#A-short-rant-about-Pocket-Casts-awesomeness" class="headerlink" title="A short rant about Pocket Casts awesomeness.."></a>A short rant about Pocket Casts awesomeness..</h2><p>What I really wanted to talk about today was how much I’m enjoying <a href="http://www.shiftyjelly.com/pocketcasts/">Pocket Casts</a> as a player for Android (though I used it on Windows Phone originally, and it ships for iPhone too).</p><p>Of course it has:</p><ol><li>Great navigation (with multiple options - by date &#x2F; by show &#x2F;etc); and</li><li>The ability to play back at variable speed (which I <em>love</em> so much - everything is better at 1.5x); and</li><li>A sensible draggable way to manage your “up next” queue of episodes for long runs; and</li><li>Easily see what’s “in progress” so you can finish things up or swipe them out of there; and</li><li>Lots of slick UI goodness with swipe left to mark done, cool progress circles for time left, etc</li></ol><p>But the thing I really love about it is the syncing! If you pay them just a few $ more for Web access, you can manage all your subscriptions via a browser on your PC. </p><p>Better still, because everything is synced, you can easily pick up the episode your were playing on your phone, and listen to a bit more on your PC, and everything remembers where you’re up to!</p><p><img src="/glen/glen/images/2016/pocket-casts-web.jpg" alt="Pocket Casts on the Web is Capital A Awesome"></p><h2 id="So-whatcha-listening-to-these-days"><a href="#So-whatcha-listening-to-these-days" class="headerlink" title="So, whatcha listening to these days?"></a>So, whatcha listening to these days?</h2><p>I’m always a bit interested in what people are listening to in the Podcast department, so here are a few of my faves, in case you need some more commute&#x2F;exercise background listening action…</p><h3 id="Developer-Related"><a href="#Developer-Related" class="headerlink" title="Developer Related"></a>Developer Related</h3><ul><li><a href="https://www.devrant.io/podcast">The devRant Podcast</a> - just starting out, but cool guests so far!</li><li><a href="http://www.adventuresinangular.com/">Adventures in Angular</a> - I’m all in on Angular, and I really like this show (even just to stay current).</li><li><a href="http://groovypodcast.podbean.com/">The Groovy Podcast</a> - back in the day I was one of the hosts, so I like to stay connected. BTW - it’s WAY improved from when I was on it!</li><li><a href="http://www.hanselminutes.com/">Hanelminutes</a> - guests are always a little left of centre and always 30 minutes. </li><li><a href="http://www.dotnetrocks.com/">.NET Rocks!</a> - even though I don’t do much in the MS space, these guys are prolific and always have diverse guests on who aren’t MS focussed.</li></ul><h3 id="Life-Stuff"><a href="#Life-Stuff" class="headerlink" title="Life Stuff"></a>Life Stuff</h3><ul><li><a href="http://revisionisthistory.com/">Revisionist History</a> - Malcolm Gladwell’s amazingly challenging podcast on all things under-researched. Worth it for the production value alone!</li><li><a href="http://www.fourhourworkweek.com/">The Tim Ferriss Show</a> - Interviews super interesting folk and pulls apart some of their world view and life philosophy. Long, but interesting. </li><li><a href="http://www.artofmanliness.com/">The Art of Manliness</a> - Don’t be put off by the title, this is actually a really progressive, practical and intellectual show. The host is an ex-layer and always polished.</li></ul><h3 id="Business-and-Entrepreneur-Stuff"><a href="#Business-and-Entrepreneur-Stuff" class="headerlink" title="Business and Entrepreneur Stuff"></a>Business and Entrepreneur Stuff</h3><ul><li><a href="http://fizzle.fm/">The Fizzle Show — Heart &amp; Hustle, Self Employment &amp; Creative Business</a> - I love these guys. All heart and hustle without the sketchy online business stuff. Somewhat quirky humor, but it works for me!</li><li><a href="http://www.smartpassiveincome.com/">The Smart Passive Income Podcast</a> - Pat Flynn is just great. I have learned heaps from this show about how to improve my business game.</li><li><a href="http://businessbootcamppodcast.com/">Business Bootcamp Podcast w&#x2F; Mike Andes</a> - tons of really actionable stuff on this one. And always short!</li></ul><h3 id="Spirituality"><a href="#Spirituality" class="headerlink" title="Spirituality"></a>Spirituality</h3><ul><li><a href="http://robbell.podbean.com/">The RobCast</a> - there is only one Rob Bell, and he’s jam packed full of awesome. I would love to communicate and connect like this guy.</li><li><a href="http://theliturgists.podbean.com/">The Liturgists</a> - love these guys - arty, sciency, inclusive, non-judgemental Jesus stuff. Without the hating. </li><li><a href="http://whchurch.org/sermons-media/sermons">Woodland Hills Church</a> - The best of the more trad Sunday sermon thing. If there were Greg Boyd T-shirts on sale, I would buy one!</li></ul><h2 id="Anyways…"><a href="#Anyways…" class="headerlink" title="Anyways…"></a>Anyways…</h2><p>There’s a bunch of things to get you started. And do check out <a href="http://www.shiftyjelly.com/pocketcasts/">Pocket Casts</a> if you’re in the market for a good player!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Now that I’ve established some routines around my exercise habits, I’m finding that I’m listening to a lot more podcasts. And there is some epic free content out there these days (more on that later).&lt;/p&gt;
&lt;h2 id=&quot;A-short-rant-about-Pocket-Casts-awesomeness&quot;&gt;&lt;a href=&quot;#A-short-rant-about-Pocket-Casts-awesomeness&quot; class=&quot;headerlink&quot; title=&quot;A short rant about Pocket Casts awesomeness..&quot;&gt;&lt;/a&gt;A short rant about Pocket Casts awesomeness..&lt;/h2&gt;&lt;p&gt;What I really wanted to talk about today was how much I’m enjoying &lt;a href=&quot;http://www.shiftyjelly.com/pocketcasts/&quot;&gt;Pocket Casts&lt;/a&gt; as a player for Android (though I used it on Windows Phone originally, and it ships for iPhone too).&lt;/p&gt;
&lt;p&gt;Of course it has:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Great navigation (with multiple options - by date &amp;#x2F; by show &amp;#x2F;etc); and&lt;/li&gt;
&lt;li&gt;The ability to play back at variable speed (which I &lt;em&gt;love&lt;/em&gt; so much - everything is better at 1.5x); and&lt;/li&gt;
&lt;li&gt;A sensible draggable way to manage your “up next” queue of episodes for long runs; and&lt;/li&gt;
&lt;li&gt;Easily see what’s “in progress” so you can finish things up or swipe them out of there; and&lt;/li&gt;
&lt;li&gt;Lots of slick UI goodness with swipe left to mark done, cool progress circles for time left, etc&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But the thing I really love about it is the syncing! If you pay them just a few $ more for Web access, you can manage all your subscriptions via a browser on your PC. &lt;/p&gt;
&lt;p&gt;Better still, because everything is synced, you can easily pick up the episode your were playing on your phone, and listen to a bit more on your PC, and everything remembers where you’re up to!&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/pocket-casts-web.jpg&quot; alt=&quot;Pocket Casts on the Web is Capital A Awesome&quot;&gt;&lt;/p&gt;
&lt;h2 id=&quot;So-whatcha-listening-to-these-days&quot;&gt;&lt;a href=&quot;#So-whatcha-listening-to-these-days&quot; class=&quot;headerlink&quot; title=&quot;So, whatcha listening to these days?&quot;&gt;&lt;/a&gt;So, whatcha listening to these days?&lt;/h2&gt;&lt;p&gt;I’m always a bit interested in what people are listening to in the Podcast department, so here are a few of my faves, in case you need some more commute&amp;#x2F;exercise background listening action…&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>How To Ship Your Hobby Project in 30 Days</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/10/13/ship-your-side-project.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/10/13/ship-your-side-project.html</id>
    <published>2016-10-13T04:50:21.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>A few days ago I started a new series on YouTube called <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmvgZA5pjyljKdmlqtFeU3P">Ship Your Hobby Project in 30 Days</a> and I’m really enjoying it.</p><p>One of the best ways to level up as a programmer is by having a side project. It gives you a great way to learn something new by actually doing (the best way to learn) - and also gives you an internal motivation bump through the exhilaration of shipping. </p><p>And I’m all about the shipping.</p><p><img src="/glen/glen/images/2016/its-all-about-shipping.jpg" alt="It&#39;s all about shipping"> </p><p>A whole bunch of people have been gradually coming on board and signing up for my <a href="http://www.subscribepage.com/o1p8o7">Motivated Programmer</a> newsletter to keep themselves honest and moving forward. And they’ve been keeping themselves honest by sending my their one-sentence app descriptions. It’s been awesome!</p><p>I’ve found the people signing up super positive and have been joining in the fun myself. We’ve just completed the lesson 3 on <a href="https://www.youtube.com/watch?v=e6fvaEQ90dk">Wireframing and Just Enough Planning</a> where we used <a href="http://e.ggtimer.com/">e.ggtimer.com</a> to smash through our wireframing and module planning. </p><p>Here’s my whiteboard version for accountability:</p><p><img src="/glen/glen/images/2016/wireframe-puppymail.jpg" alt="Wireframe and Minimal Plan for PuppyMail"> </p><p>If your GitHub repo is full of half-finished stuff, and you’re keen to jump into a community that is non-judgement, it’s totally worth hanging out with us. First step is to spend just 10 minutes a day and start working your way through <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmvgZA5pjyljKdmlqtFeU3P">Ship Your Hobby Project in 30 Days</a>.</p><p>Can’t wait to show off what the students build next month. Super exited!</p><p><img src="/glen/glen/images/2016/motivated-programmer-logo.png" alt="Let&#39;s Get Motivated!"> </p>]]></content>
    
    
    <summary type="html">&lt;p&gt;A few days ago I started a new series on YouTube called &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmvgZA5pjyljKdmlqtFeU3P&quot;&gt;Ship Your Hobby Project in 30 Days&lt;/a&gt; and I’m really enjoying it.&lt;/p&gt;
&lt;p&gt;One of the best ways to level up as a programmer is by having a side project. It gives you a great way to learn something new by actually doing (the best way to learn) - and also gives you an internal motivation bump through the exhilaration of shipping. &lt;/p&gt;
&lt;p&gt;And I’m all about the shipping.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/its-all-about-shipping.jpg&quot; alt=&quot;It&amp;#39;s all about shipping&quot;&gt; &lt;/p&gt;
&lt;p&gt;A whole bunch of people have been gradually coming on board and signing up for my &lt;a href=&quot;http://www.subscribepage.com/o1p8o7&quot;&gt;Motivated Programmer&lt;/a&gt; newsletter to keep themselves honest and moving forward. And they’ve been keeping themselves honest by sending my their one-sentence app descriptions. It’s been awesome!&lt;/p&gt;
&lt;p&gt;I’ve found the people signing up super positive and have been joining in the fun myself. We’ve just completed the lesson 3 on &lt;a href=&quot;https://www.youtube.com/watch?v=e6fvaEQ90dk&quot;&gt;Wireframing and Just Enough Planning&lt;/a&gt; where we used &lt;a href=&quot;http://e.ggtimer.com/&quot;&gt;e.ggtimer.com&lt;/a&gt; to smash through our wireframing and module planning. &lt;/p&gt;
&lt;p&gt;Here’s my whiteboard version for accountability:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/wireframe-puppymail.jpg&quot; alt=&quot;Wireframe and Minimal Plan for PuppyMail&quot;&gt; &lt;/p&gt;
&lt;p&gt;If your GitHub repo is full of half-finished stuff, and you’re keen to jump into a community that is non-judgement, it’s totally worth hanging out with us. First step is to spend just 10 minutes a day and start working your way through &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmvgZA5pjyljKdmlqtFeU3P&quot;&gt;Ship Your Hobby Project in 30 Days&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Can’t wait to show off what the students build next month. Super exited!&lt;/p&gt;</summary>
    
    
    
    
  </entry>
  
  <entry>
    <title>Securing Angular 2 Routes with OAuth and Firebase</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/10/04/firebase-oauth-angular2.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/10/04/firebase-oauth-angular2.html</id>
    <published>2016-10-04T06:02:42.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Today on the show we explore securing Angular 2 routes. And we’ll use OAuth, Firebase and Google (or your preferred OAuth provider) to get us there.</p><p>You can grab the source on the <a href="https://github.com/glenasmith/angularfire2-qotd">GitHub Repo</a>.</p><p>Don’t forget to <a href="https://www.youtube.com/c/FreshBytecode">Subscribe</a> to my <a href="https://www.youtube.com/c/FreshBytecode">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts</p><iframe width="560" height="315" src="https://www.youtube.com/embed/dLdcr0HFSg4" frameborder="0" allowfullscreen></iframe><p>Here’s the script if you’d like to follow along at home!</p><p>[ ] Discuss the plan for today - use Google authentication to login to your app. Pluck Image URLs along the way.</p><p>[ ] Check out last weeks show to get up to speed on the QOTD app</p><p>[ ] Turn on authentication in your application (auth&#x2F;signin method)</p><p>[ ] Configure your module to turn on authentication methods you prefer</p><pre><code>export const firebaseAuthConfig = &#123;  provider: AuthProviders.Google,  method: AuthMethods.Popup&#125;// and in imports...AngularFireModule.initializeApp(firebaseConfig, firebaseAuthConfig),</code></pre><p>[ ] Now to secure the routes in <code>app.routing.ts</code></p><pre><code>const appRoutes: Routes = [    &#123; path: &#39;&#39;,  redirectTo: &#39;/quotes&#39;,  pathMatch: &#39;full&#39;&#125;,    &#123; path: &#39;quotes&#39;, component: QuotelistComponent, canActivate: [LoggedInGuard] &#125;,    &#123; path: &#39;login&#39;, component: LoginComponent &#125;];export const appRoutingProviders: any[] = [    LoggedInGuard];</code></pre><p>[ ] Implement <code>login.guard.ts</code></p><pre><code>import &#123; LoginService &#125; from &#39;./login.service&#39;;import &#123; Injectable &#125; from &#39;@angular/core&#39;;import &#123; Router, CanActivate &#125; from &#39;@angular/router&#39;;@Injectable()export class LoggedInGuard implements CanActivate &#123;    constructor(private loginService: LoginService, private router: Router) &#123; &#125;    canActivate(): boolean &#123;        console.log(&quot;Guard function has been invoked&quot;);        let authenticated = false;        if (this.loginService.isAuthenticated) &#123;            authenticated = true;        &#125;        else &#123;            this.router.navigate([&#39;/login&#39;]);        &#125;        console.log(&quot;Returning from Guard function with: &quot; + authenticated);        return authenticated;    &#125;&#125;</code></pre><p>[ ] Explore the actual login service</p><p>[ ] Add some markup to the menu</p><pre><code>&lt;div class=&quot;right item&quot; *ngIf=&#39;loginService.isAuthenticated&#39;&gt;    &lt;a class=&quot;item&quot; &gt;        &lt;img class=&quot;ui avatar image&quot; [src]=&#39;loginService.photoUrl&#39;&gt;        &lt;span&gt;&#123;&#123; loginService.displayName &#125;&#125; &lt;/span&gt;        &lt;/a&gt;    &lt;/div&gt;    &lt;div class=&quot;right item&quot; *ngIf=&#39;!loginService.isAuthenticated&#39;&gt;    &lt;a class=&quot;ui inverted button&quot; routerLink=&#39;/quotes&#39;&gt;Log in&lt;/a&gt;&lt;/div&gt;</code></pre><p>[ ] <a href="https://github.com/glenasmith/angularfire2-qotd">GitHub repo</a> has localStorage to cache oAuth tokens</p><p>[ ] Next time we’ll look at editing values.</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Today on the show we explore securing Angular 2 routes. And we’ll use OAuth, Firebase and Google (or your preferred OAuth provider) to get us there.&lt;/p&gt;
&lt;p&gt;You can grab the source on the &lt;a href=&quot;https://github.com/glenasmith/angularfire2-qotd&quot;&gt;GitHub Repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Don’t forget to &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/dLdcr0HFSg4&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Here’s the script if you’d like to follow along at home!&lt;/p&gt;
&lt;p&gt;[ ] Discuss the plan for today - use Google authentication to login to your app. Pluck Image URLs along the way.&lt;/p&gt;
&lt;p&gt;[ ] Check out last weeks show to get up to speed on the QOTD app&lt;/p&gt;
&lt;p&gt;[ ] Turn on authentication in your application (auth&amp;#x2F;signin method)&lt;/p&gt;
&lt;p&gt;[ ] Configure your module to turn on authentication methods you prefer&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export const firebaseAuthConfig = &amp;#123;
  provider: AuthProviders.Google,
  method: AuthMethods.Popup
&amp;#125;	

// and in imports...
AngularFireModule.initializeApp(firebaseConfig, firebaseAuthConfig),
&lt;/code&gt;&lt;/pre&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
    <category term="Firebase" scheme="http://blogs.bytecode.com.au/glen/tags/Firebase/"/>
    
  </entry>
  
  <entry>
    <title>Hacking a Serverless QOTD App with Angular2, Firebase and AngularFire2</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/09/27/qotd-with-angular2-firebase.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/09/27/qotd-with-angular2-firebase.html</id>
    <published>2016-09-27T03:55:07.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Serverless architectures are so hot right now! Today on the show we dive into <a href="https://firebase.google.com/">Firebase</a> with Angular2 using the <a href="https://github.com/angular/angularfire2">AngularFire2</a> library.</p><p>We’ll be a dynamic Quote of the Day application which updates from the server in real time. Get out of here! Real time!</p><p>You can grab the code for today’s episode on <a href="https://github.com/glenasmith/angularfire2-qotd">GitHub</a>.</p><p><img src="/glen/glen/images/2016/qotd.png" alt="Real Time Quote Action"></p><p>Don’t forget to <a href="https://www.youtube.com/c/FreshBytecode">Subscribe</a> to my <a href="https://www.youtube.com/c/FreshBytecode">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts</p><iframe width="560" height="315" src="https://www.youtube.com/embed/994lOyULgS4" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] Discuss the plan for today - use remote db to populate a list of quotes - with live update when server changes</p><p>[ ] Create a new app </p><pre><code>ng new qotd</code></pre><p>[ ] I’ve added <a href="http://semantic-ui.com/">Semantic UI</a> to the <code>index.html</code> in the root  </p><pre><code>&lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/semantic-ui/2.2.2/semantic.min.css&quot;&gt;&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.js&quot;&gt;&lt;/script&gt;&lt;script src=&quot;https://cdn.jsdelivr.net/semantic-ui/2.2.2/semantic.min.js&quot;&gt;&lt;/script&gt;</code></pre><p>[ ] I’ve also customised the <code>index.html</code> to use the <a href="http://semantic-ui.com/usage/layout.html">Home Page</a> layout from Semantic UI (scroll down that page to see it in action)</p><p>[ ] Install the firebase deps</p><pre><code>npm install firebase angularfire2 --save</code></pre><p>[ ] Sign up for a firebase account:</p><pre><code>https://console.firebase.google.com</code></pre><p>[ ] Create some data</p><p>[ ] Edit the read and write action on the your table (the rules tab) - so you can read without authenticating</p><pre><code>&#123;    &quot;rules&quot;: &#123;        &quot;.read&quot;: &quot;true&quot;,        &quot;.write&quot;: &quot;auth != null&quot;    &#125;&#125;</code></pre><p>[ ] Configure your <code>app.module.ts</code> to use Firebase</p><pre><code>Update your module definitions    import * as firebase from &#39;firebase&#39;;    import &#123; AngularFireModule &#125; from &#39;angularfire2&#39;;    // Initialize Firebase    export const firebaseConfig = &#123;      apiKey: &quot;AIzaSyAtkDOebowUCsSF8efOL_0yup1DKCCan00&quot;,      authDomain: &quot;qotd-caac8.firebaseapp.com&quot;,      databaseURL: &quot;https://qotd-caac8.firebaseio.com&quot;,      storageBucket: &quot;qotd-caac8.appspot.com&quot;,      messagingSenderId: &quot;922026910241&quot;    &#125;;        @NgModule(&#123;      declarations: [        AppComponent,      ],      imports: [        BrowserModule,        FormsModule,        HttpModule,        AngularFireModule.initializeApp(firebaseConfig)      ],      providers: [],      bootstrap: [AppComponent]    &#125;)    export class AppModule &#123; &#125;</code></pre><p>[ ] Add your quote list component</p><pre><code>import &#123; Component, OnInit &#125; from &#39;@angular/core&#39;;import &#123; AngularFire, FirebaseListObservable &#125; from &#39;angularfire2&#39;;@Component(&#123;  selector: &#39;app-quotelist&#39;,  templateUrl: &#39;./quotelist.component.html&#39;,  styleUrls: [&#39;./quotelist.component.css&#39;]&#125;)export class QuotelistComponent implements OnInit &#123;  quotes: FirebaseListObservable&lt;any&gt;;  constructor(private af: AngularFire) &#123; &#125;  ngOnInit() &#123;    this.quotes = this.af.database.list(&#39;quotes&#39;, &#123;      query: &#123;        orderByChild: &#39;author&#39;      &#125;    &#125;);  &#125;&#125;</code></pre><p>[ ] Add some markup</p><pre><code>&lt;table class=&quot;ui basic table&quot; id=&quot;quoteTable&quot;&gt;  &lt;thead&gt;    &lt;tr&gt;&lt;th&gt;Id&lt;/th&gt;    &lt;th&gt;Author&lt;/th&gt;    &lt;th&gt;Quote&lt;/th&gt;  &lt;/tr&gt;&lt;/thead&gt;  &lt;tbody&gt;    &lt;tr *ngFor=&quot;let quote of quotes | async&quot;&gt;      &lt;td&gt;&#123;&#123;quote.$key&#125;&#125;&lt;/td&gt;      &lt;td&gt;&#123;&#123;quote.author&#125;&#125;&lt;/td&gt;      &lt;td&gt;&#123;&#123;quote.quote&#125;&#125;&lt;/td&gt;    &lt;/tr&gt;      &lt;/tbody&gt;&lt;/table&gt;[ ] Celebrate the awesome serverless realtime update action</code></pre>]]></content>
    
    
    <summary type="html">&lt;p&gt;Serverless architectures are so hot right now! Today on the show we dive into &lt;a href=&quot;https://firebase.google.com/&quot;&gt;Firebase&lt;/a&gt; with Angular2 using the &lt;a href=&quot;https://github.com/angular/angularfire2&quot;&gt;AngularFire2&lt;/a&gt; library.&lt;/p&gt;
&lt;p&gt;We’ll be a dynamic Quote of the Day application which updates from the server in real time. Get out of here! Real time!&lt;/p&gt;
&lt;p&gt;You can grab the code for today’s episode on &lt;a href=&quot;https://github.com/glenasmith/angularfire2-qotd&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/qotd.png&quot; alt=&quot;Real Time Quote Action&quot;&gt;&lt;/p&gt;
&lt;p&gt;Don’t forget to &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/994lOyULgS4&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] Discuss the plan for today - use remote db to populate a list of quotes - with live update when server changes&lt;/p&gt;
&lt;p&gt;[ ] Create a new app &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ng new qotd
&lt;/code&gt;&lt;/pre&gt;</summary>
    
    
    
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 21 - Deployment and Resources</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/09/21/ng-day21-deployment-and-resources.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/09/21/ng-day21-deployment-and-resources.html</id>
    <published>2016-09-21T02:14:19.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Congratulations if you’ve made it this far. Today on the show we explore doing production builds, and deploying to github pages. Then we’ll share a bunch of cool resources (down below) for the next stage in your journey!</p><p>It’s our last show in the series! But not the last show for the channel, so subscribe today!</p><p>Thanks for being so awesome!</p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/c/FreshBytecode">Subscribe</a> to my <a href="https://www.youtube.com/c/FreshBytecode">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/aK99-xV5oXw" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] First, we’ll do a production build</p><pre><code>ng build --prodng build --target=prod --env=prod</code></pre><p>[ ] Have a look at your tiny dist directory</p><p>[ ] Then we’ll deploy our app to github pages</p><pre><code>ng github-pages:deploy --message &quot;First official release of Twit-ng!&quot;</code></pre><p>[ ] Sit back and wait to be acquired    </p><p>[ ] While we’re waiting to bathe in the cash, let’s explore some cool resources</p><p>[ ] First some free stuff…</p><p>[ ] You should subscribe to <a href="http://www.ng-newsletter.com/">ng-newsletter</a> - super interesting articles. Here’s a direct link to the <a href="http://cur.ng-newsletter.com/issues/166">current issue</a> at time of writing. </p><p>[ ] If you’re into podcasts, the <a href="https://devchat.tv/adv-in-angular">Adventures in Angular</a> podcast is jam packed full of great stuff</p><p>[ ] If you’re into blogs, the <a href="http://blog.thoughtram.io/">Thoughtram</a> guys are the gold-standard for black belt Angular. Super cool dudes.</p><p>[ ] If you’re after a book, I can recommend the <a href="https://www.ng-book.com/2/">ng-book-2</a> offering. Don’t really need the screencast bundle - but the base book offering is awesome (albeit expensive)</p><p>[ ] I’m seriously thinking about putting together a $5 book package that covers just the essential stuff that I cover in these 21 days. If you’d be interested, just thumbs up this vid and I’ll take it as a call to arms!</p><p>[ ] And we’re done. Thanks for 21 days of effort and positivity. You guys have been so supportive, I have learned so much!</p><p>[ ] Subscribe to the <a href="https://www.youtube.com/c/freshbytecode">channel</a>, I’m going to keep posting vids regularly (and I’m going to be doing a Git course here shortly!).</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Congratulations if you’ve made it this far. Today on the show we explore doing production builds, and deploying to github pages. Then we’ll share a bunch of cool resources (down below) for the next stage in your journey!&lt;/p&gt;
&lt;p&gt;It’s our last show in the series! But not the last show for the channel, so subscribe today!&lt;/p&gt;
&lt;p&gt;Thanks for being so awesome!&lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/aK99-xV5oXw&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] First, we’ll do a production build&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ng build --prod
ng build --target=prod --env=prod
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Have a look at your tiny dist directory&lt;/p&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 20 - Linting and Code Coverage and Mocking</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/09/20/ng-day20-linting-code-coverage-mocking.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/09/20/ng-day20-linting-code-coverage-mocking.html</id>
    <published>2016-09-20T07:10:36.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Angular 2 has gone final! Yay! Today we’re going to look at linting, code coverage and mocking in the latest Angular CLI (Beta 14).</p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/c/FreshBytecode">Subscribe</a> to my <a href="https://www.youtube.com/c/FreshBytecode">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/SdphumIXelc" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] First, we’ll migrate everything to the latest CLI using <a href="https://github.com/angular/angular-cli/wiki/Upgrading-from-Beta.10-to-Beta.14">this migration guide</a></p><p>[ ] Basically we spark a new project, and copy our src and e2e folders over.</p><p>[ ] Next will fix the broken, by removing <code>module.id</code> everywhere, moving our assets to <code>src/assets</code> (and fix matching links). Tests are a world of broken, too. We’ll talk about them shortly.</p><p>[ ] Let’s lint our file</p><pre><code>ng lint</code></pre><p>[ ] What that actually does is just run <code>npm run lint</code></p><pre><code>&quot;scripts&quot;: &#123;    &quot;start&quot;: &quot;ng serve&quot;,    &quot;lint&quot;: &quot;tslint \&quot;src/**/*.ts\&quot;&quot;,</code></pre><p>[ ] How to configure your linting rules via <code>tslint.json</code> in the root of your project</p><pre><code>&quot;no-trailing-whitespace&quot;: false,&quot;indent&quot;: [  true,  &quot;spaces&quot;],</code></pre><p>[ ] And let’s tidy up our <code>Tweet</code> class appropriately</p><p>[ ] Look up the docs</p><pre><code>ng doc TestBed</code></pre><p>[ ] Let’s have a look at code coverage</p><pre><code>ng test</code></pre><p>[ ] Let’s enhance our <code>FeedComponent</code> with an mock call</p><pre><code>it(&#39;should retrieve things on init..&#39;, () =&gt; &#123;    let fixture = TestBed.createComponent(FeedComponent);    let app = fixture.debugElement.componentInstance as FeedComponent;    expect(app.loaded).toBeFalsy();    expect(app.tweets.length).toEqual(0);    app.ngOnInit();    expect(app.tweets.length).toEqual(2);    expect(app.loaded).toBeTruthy();  &#125;);</code></pre><p>[ ] And the same for favorites and retweets</p><pre><code>it(&#39;should favorite and retweet appropriately..&#39;, () =&gt; &#123;    let fixture = TestBed.createComponent(FeedComponent);    let app = fixture.debugElement.componentInstance as FeedComponent;    let tweet = new Tweet(125, &#39;Another Mock Tweet&#39;, &#39;Glen&#39;, new Date(), [], []);    expect(tweet.favorites.length).toEqual(0);    app.OnFavorite(tweet);    expect(tweet.favorites.length).toEqual(1);    expect(tweet.retweets.length).toEqual(0);    app.OnRetweet(tweet);    expect(tweet.retweets.length).toEqual(1);  &#125;);</code></pre><p>[ ] Celebrate our awesome coverage!</p><p>[ ] Tomorrow we look at where to go from here</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Angular 2 has gone final! Yay! Today we’re going to look at linting, code coverage and mocking in the latest Angular CLI (Beta 14).&lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/SdphumIXelc&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] First, we’ll migrate everything to the latest CLI using &lt;a href=&quot;https://github.com/angular/angular-cli/wiki/Upgrading-from-Beta.10-to-Beta.14&quot;&gt;this migration guide&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[ ] Basically we spark a new project, and copy our src and e2e folders over.&lt;/p&gt;
&lt;p&gt;[ ] Next will fix the broken, by removing &lt;code&gt;module.id&lt;/code&gt; everywhere, moving our assets to &lt;code&gt;src/assets&lt;/code&gt; (and fix matching links). Tests are a world of broken, too. We’ll talk about them shortly.&lt;/p&gt;
&lt;p&gt;[ ] Let’s lint our file&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ng lint
&lt;/code&gt;&lt;/pre&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 19 - End To End Testing</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/09/16/ng-day19-end-to-end-testing.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/09/16/ng-day19-end-to-end-testing.html</id>
    <published>2016-09-16T05:18:14.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Today we’re going to look at integration testing using the bundled ng end to end testing tool called <a href="http://www.protractortest.org/">Protractor</a>. </p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/c/FreshBytecode">Subscribe</a> to my <a href="https://www.youtube.com/c/FreshBytecode">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/4_gSyiwi_uo" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] First, we’ll run our integration test suite</p><pre><code>ng e2e</code></pre><p>[ ] Explore the directory e2e-spec.ts &amp; .po.ts files</p><p>[ ] We’ll explore the role of Page objects to abstract elements and localise changes</p><p>[ ] Implement our <code>TwitNgPage</code> object (I would typically rename to <code>FeedPage</code>)</p><pre><code>export class TwitNgPage &#123;  navigateTo() &#123;    return browser.get(&#39;/feed&#39;);  &#125;  postTweet(tweetText) &#123;    element(by.name(&quot;body&quot;)).sendKeys(tweetText);     element(by.css(&quot;button&quot;)).click();  &#125; &#125;</code></pre><p>[ ] Discuss selectors <code>by.name</code> <code>by.id</code> and <code>by.css</code> (not <code>by.model</code>)</p><p>[ ] Use the debugger</p><pre><code>browser.pause();</code></pre><p>[ ] And add an assertion to <code>app.e2e-spec.ts</code></p><pre><code>it(&quot;Should post a tweet&quot;, () =&gt; &#123;    page.navigateTo();    page.postTweet(&quot;This is awesome&quot;);    expect(page.getFeedCount()).toEqual(6);  &#125;);</code></pre><p>[ ] Implement our selector in <code>app.po.ts</code></p><pre><code>  getFeedCount()  &#123;    return element.all(by.css(&quot;.comment&quot;)).count();  &#125;</code></pre><p>[ ] Let’s confirm it’s working by getting the text of the tweet in <code>app.po.ts</code></p><pre><code>getLatestTweet() &#123;    return element.all(by.css(&quot;.comment .content .text&quot;)).get(0).getText();&#125;</code></pre><p>[ ] And asserting it in <code>app.e2e-spec.ts</code></p><pre><code>expect(page.getLatestTweet()).toEqual(&quot;This is awesome&quot;);</code></pre><p>[ ] Let’s also test our retweet action in <code>app.e2e-spec.ts</code></p><pre><code>it(&quot;Should increment retweet count&quot;, () =&gt; &#123;    page.navigateTo();    page.retweetLatestTweet();    var rtCount = page.getLatestTweetRetweetCount();    expect(rtCount).toEqual(&quot;2 Retweets&quot;);  &#125;);</code></pre><p>[ ] And implement the logic to retweet&#x2F;count to the Page in <code>app.po.ts</code></p><pre><code>  retweetLatestTweet() &#123;    element.all(by.css(&quot;.comment .content .actions .retweet&quot;)).get(0).click();  &#125;  getLatestTweetRetweetCount() &#123;    return element.all(by.css(&quot;.comment .content .actions .retweet&quot;)).get(0).getText();  &#125;</code></pre><p>[ ] We have smashed end to end testing!</p><p>[ ] Tomorrow we look at quality tools</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Today we’re going to look at integration testing using the bundled ng end to end testing tool called &lt;a href=&quot;http://www.protractortest.org/&quot;&gt;Protractor&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/4_gSyiwi_uo&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] First, we’ll run our integration test suite&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ng e2e
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Explore the directory e2e-spec.ts &amp;amp; .po.ts files&lt;/p&gt;
&lt;p&gt;[ ] We’ll explore the role of Page objects to abstract elements and localise changes&lt;/p&gt;
&lt;p&gt;[ ] Implement our &lt;code&gt;TwitNgPage&lt;/code&gt; object (I would typically rename to &lt;code&gt;FeedPage&lt;/code&gt;)&lt;/p&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 18 - Reactive Forms</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/09/12/ng-day18-reactive-forms.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/09/12/ng-day18-reactive-forms.html</id>
    <published>2016-09-12T20:16:24.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>With Reactive Forms, our validation and binding are configured in the backing code rather than the markup. Today, we’ll take yesterday’s template-driven form and convert it to a reactive form, and in the process you can decide which style you like better. </p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/c/FreshBytecode">Subscribe</a> to my <a href="https://www.youtube.com/c/FreshBytecode">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/QS9ObFBkBW8" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] First, we’ll update our module list to import reactive forms</p><pre><code>import &#123; FormsModule, ReactiveFormsModule &#125; from &#39;@angular/forms&#39;;imports: [ BrowserModule, FormsModule, ReactiveFormsModule, routing, HttpModule,</code></pre><p>[ ] We’ll update our template code to spark the form model</p><pre><code>import &#123; FormControl, FormGroup, FormBuilder, Validators &#125; from &#39;@angular/forms&#39;;form = new FormGroup(&#123;    username : new FormControl(),    password : new FormControl(),    rememberme : new FormControl()  &#125;)</code></pre><p>[ ] Remove all our <code>ngModel</code> directive</p><p>[ ] Wire our form to our model </p><pre><code>&lt;form class=&quot;ui form error&quot; [formGroup]=&#39;form&#39; name=&#39;username&#39; becomes formControlName=&#39;username&#39; etc</code></pre><p>[ ] Test our form model</p><p>[ ] Add some validation logic</p><pre><code>form = new FormGroup(&#123;    username : new FormControl(&#39;&#39;,[ Validators.required] ),    password : new FormControl(&#39;&#39;, [ Validators.required] ),    rememberme : new FormControl(true)  &#125;)</code></pre><p>[ ] Refresh our validation logic</p><pre><code>&lt;div *ngIf=&#39;form.controls.username.invalid &amp;&amp; form.controls.username.dirty&#39; class=&quot;ui error message&quot;&gt;&lt;p&gt;Username is a required field&lt;/p&gt;&lt;/div&gt;</code></pre><p>[ ] Refactor to use the FormBuilder DSL</p><pre><code>  public form : FormGroup;  constructor(private formBuilder : FormBuilder) &#123; &#125;  ngOnInit() &#123;    this.form = this.formBuilder.group(&#123;      username: [&#39;&#39;, Validators.required],      password: [&#39;&#39;, Validators.required],      rememberme: [true],    &#125;)  &#125;</code></pre><p>[ ] Winning with reactive forms complete</p><p>[ ] Tomorrow we’ll tackle End to End testing</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;With Reactive Forms, our validation and binding are configured in the backing code rather than the markup. Today, we’ll take yesterday’s template-driven form and convert it to a reactive form, and in the process you can decide which style you like better. &lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/QS9ObFBkBW8&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] First, we’ll update our module list to import reactive forms&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import &amp;#123; FormsModule, ReactiveFormsModule &amp;#125; from &amp;#39;@angular/forms&amp;#39;;

imports: [ BrowserModule, FormsModule, ReactiveFormsModule, routing, HttpModule,
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] We’ll update our template code to spark the form model&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import &amp;#123; FormControl, FormGroup, FormBuilder, Validators &amp;#125; from &amp;#39;@angular/forms&amp;#39;;

form = new FormGroup(&amp;#123;
    username : new FormControl(),
    password : new FormControl(),
    rememberme : new FormControl()
  &amp;#125;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Remove all our &lt;code&gt;ngModel&lt;/code&gt; directive&lt;/p&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 17 - Template Driven Forms</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/09/11/ng-day17-template-driven-forms.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/09/11/ng-day17-template-driven-forms.html</id>
    <published>2016-09-11T20:07:41.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Today we’re going to look at template-driven approach to forms with the wonders of ngModel. Tomorrow we’ll look at the reactive approach to forms using backing code for validation config.</p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/c/FreshBytecode">Subscribe</a> to my <a href="https://www.youtube.com/c/FreshBytecode">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/ENgl47TiqIU" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] First, let’s generate a login form</p><pre><code>ng g c login</code></pre><p>[ ] And add it to our module in <code>app.module.ts</code></p><pre><code>import &#123; LoginComponent &#125; from &#39;./login&#39;;declarations: [ AppComponent, FeedComponent, MenuComponent, FriendsComponent, FriendComponent, MessagesComponent, LoginComponent ],</code></pre><p>[ ] And add it to our router in <code>app.routes.ts</code></p><pre><code>import &#123; LoginComponent &#125; from &#39;./login&#39;;&#123; path: &#39;login&#39;, component: LoginComponent &#125;,</code></pre><p>[ ] And add that router link to our menu</p><pre><code>&lt;a class=&quot;ui item&quot; routerLink=&quot;/login&quot; routerLinkActive=&quot;active&quot;&gt;</code></pre><p>[ ] Demonstrate the login page</p><p>[ ] Now create a rough login form</p><pre><code>&lt;form class=&quot;ui form error&quot;&gt;  &lt;div class=&quot;field&quot;&gt;    &lt;label&gt;User Name&lt;/label&gt;    &lt;input name=&quot;username&quot; placeholder=&quot;User Name&quot; type=&quot;text&quot; required &gt;  &lt;/div&gt;  &lt;div class=&quot;field&quot;&gt;    &lt;label&gt;Password&lt;/label&gt;    &lt;input name=&quot;password&quot; placeholder=&quot;Password&quot; type=&quot;password&quot;&gt;  &lt;/div&gt;  &lt;div class=&quot;field&quot;&gt;    &lt;div class=&quot;ui checkbox&quot;&gt;      &lt;input name=&quot;rememberme&quot; tabindex=&quot;0&quot; type=&quot;checkbox&quot;&gt;      &lt;label&gt;Remember Me&lt;/label&gt;    &lt;/div&gt;  &lt;/div&gt;  &lt;button class=&quot;ui button primary&quot; type=&quot;submit&quot;&gt;Submit&lt;/button&gt;&lt;/form&gt;</code></pre><p>[ ] Now we’re going to use the ngForm module to do magic in creating a form backing model (not our domain model!)</p><pre><code>&lt;form class=&quot;ui form error&quot; #form=&quot;ngForm&quot;</code></pre><p>[ ] Add <code>ngModel</code> to each input field</p><p>[ ] Add a pipe to see the data in action</p><pre><code>&#123;&#123; form.value | json &#125;&#125;</code></pre><p>[ ] Handle the form values in OnSubmit()</p><pre><code>(ngSubmit)=&#39;OnSubmit(form.value)&#39; OnSubmit(formJson) &#123;    console.log(formJson);  &#125;</code></pre><p>[ ] Let’s look at the form model for validation</p><pre><code>&lt;input #username=&#39;ngModel&#39; ...&gt;  &lt;div *ngIf=&#39;username.invalid &amp;&amp; username.dirty&#39; class=&quot;ui error message&quot;&gt;&lt;p&gt;Username is a required field&lt;/p&gt;&lt;/div&gt;</code></pre><p>[ ] You can also structure JSON, and do validity checking on whole groups (eg an address)</p><pre><code>ngModelGroup=&#39;blah&#39;</code></pre><p>[ ] Celebrate the win of template-driven forms</p><p>[ ] Tomorrow we’ll tackle reactive forms</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Today we’re going to look at template-driven approach to forms with the wonders of ngModel. Tomorrow we’ll look at the reactive approach to forms using backing code for validation config.&lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/ENgl47TiqIU&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] First, let’s generate a login form&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ng g c login
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] And add it to our module in &lt;code&gt;app.module.ts&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import &amp;#123; LoginComponent &amp;#125; from &amp;#39;./login&amp;#39;;

declarations: [ AppComponent, FeedComponent, MenuComponent, FriendsComponent, FriendComponent, MessagesComponent, LoginComponent ],
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] And add it to our router in &lt;code&gt;app.routes.ts&lt;/code&gt;&lt;/p&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 16 - HTTP Error Handling with Observables</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/09/08/ng-day16-http-error-handling-with-observables.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/09/08/ng-day16-http-error-handling-with-observables.html</id>
    <published>2016-09-08T19:30:07.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Bad things can happen when working with remote services. Today we explore error handling in an Observables context (in both the service tier and user facing components).</p><p>And we revisit our “Loading…” state to tidy things up on initial page load.</p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/c/FreshBytecode">Subscribe</a> to my <a href="https://www.youtube.com/c/FreshBytecode">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/h2gOctvobOc" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] First, fix our import</p><pre><code>import &#123; Observable &#125; from &#39;rxjs/Rx&#39;;</code></pre><p>[ ] Implement our <code>getCurrentFeed()</code> method to catch errors</p><pre><code>return this.http.get(&#39;/api/tweets&#39;).map((resp: Response) =&gt; &#123;  console.log(resp.json());  var fetchedTweets = [];  for (let tweet of resp.json().data) &#123;    fetchedTweets.push(this.getTweetFromJson(tweet));  &#125;  return fetchedTweets as Array&lt;Tweet&gt;;&#125;).catch(this.errorHandler);</code></pre><p>[ ] Implement our error handler (service side) for diagnostic&#x2F;forensics</p><pre><code>errorHandler(err) &#123;    console.log(err);    return Observable.throw(err);  &#125;</code></pre><p>[ ] Update our feed component to catch the error (second arg to subscribe) - this should be our user facing error!</p><pre><code>ngOnInit() &#123;this.feedService.getCurrentFeed().subscribe( (newTweets) =&gt; &#123;  this.tweets = newTweets;&#125;, ( error ) =&gt; &#123;  this.errorText = error;&#125;);</code></pre><p>[ ] Display the error text in the component (conditionally) after we render the form, perhaps, but before the timeline…</p><pre><code>&lt;div *ngIf=&quot;errorText&quot; class=&quot;ui negative message&quot;&gt;  &lt;i class=&quot;close icon&quot;&gt;&lt;/i&gt;  &lt;div class=&quot;header&quot;&gt;    &#123;&#123; errorText &#125;&#125;  &lt;/div&gt;&lt;/div&gt;</code></pre><p>[ ] Throw an error to test it out!!!</p><pre><code>throw &quot;Internal Error&quot;;</code></pre><p>[ ] There are scenarios when you do want to trip these errors yourself - for example, bad status codes come back. Let’s updated <code>updateTweet()</code> in our feed service</p><pre><code>return this.http.put(url, body).map(      (resp: Response) =&gt; &#123;        console.log(resp);        if (resp.status == 204) &#123;          console.log(&quot;Success. Yay!&quot;);        &#125; else &#123;        throw `Error fetching tweet $&#123;tweet.id&#125;. Received status code: $&#123;resp.status&#125;`;      &#125;      &#125;).catch(this.errorHandler);</code></pre><p>[ ] Finally, let’s handle the “Loading..” screen scenario. In our feed component backing class, we’ll add a <code>loaded</code> property and use it as a toggle. The third argument to a subscribe is an “on complete” or finally block.</p><pre><code>loaded = false;ngOnInit() &#123;    this.feedService.getCurrentFeed().subscribe( (newTweets) =&gt; &#123;      this.tweets = newTweets;    &#125;, ( error ) =&gt; &#123;      this.errorText = error;    &#125;, () =&gt; &#123;      this.loaded = true;    &#125;);  &#125;</code></pre><p>[ ] Update the markup and we’re done</p><pre><code>&lt;div *ngIf=&quot;loaded&quot;&gt;    // existing markup..&lt;/div&gt;&lt;div *ngIf=&#39;!loaded&#39;&gt;  &lt;h2&gt;Loading...&lt;/h2&gt;&lt;/div&gt;</code></pre><p>[ ] Let’s slow down our fake request timing in our app.module.ts</p><pre><code>InMemoryWebApiModule.forRoot(MockDatabaseService, &#123;     delay: 3000,  rootPath: &#39;api/&#39;&#125;)</code></pre><p>[ ] Robustness award unlocked! (level 1 :-)</p><p>[ ] Next up we’ll start looking at Form validation (continuing our robust theme).</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Bad things can happen when working with remote services. Today we explore error handling in an Observables context (in both the service tier and user facing components).&lt;/p&gt;
&lt;p&gt;And we revisit our “Loading…” state to tidy things up on initial page load.&lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/h2gOctvobOc&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] First, fix our import&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import &amp;#123; Observable &amp;#125; from &amp;#39;rxjs/Rx&amp;#39;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Implement our &lt;code&gt;getCurrentFeed()&lt;/code&gt; method to catch errors&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;return this.http.get(&amp;#39;/api/tweets&amp;#39;).map((resp: Response) =&amp;gt; &amp;#123;
  console.log(resp.json());
  var fetchedTweets = [];
  for (let tweet of resp.json().data) &amp;#123;
    fetchedTweets.push(this.getTweetFromJson(tweet));
  &amp;#125;
  return fetchedTweets as Array&amp;lt;Tweet&amp;gt;;
&amp;#125;).catch(this.errorHandler);
&lt;/code&gt;&lt;/pre&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 15 - HTTP CRUD operations with Observables</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/09/07/ng-day15-http-crud-operations-with-observables.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/09/07/ng-day15-http-crud-operations-with-observables.html</id>
    <published>2016-09-07T20:02:38.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>It’s finally time to introduce some Http CRUD implementation! Today on the show we use yesterday mock in-memory RESTful Http service to <code>get()</code>, <code>post()</code>, and <code>put()</code> our way to remote data!</p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/c/FreshBytecode">Subscribe</a> to my <a href="https://www.youtube.com/c/FreshBytecode">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/ABNB02walbk" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] Implement our <code>getCurrentFeed()</code> method</p><pre><code>private getTweetFromJson(obj: Tweet): Tweet &#123;    return new Tweet(      obj.id, obj.body, obj.author, obj.date, obj.retweets, obj.favorites)  &#125;  getCurrentFeed(): Observable&lt;Tweet[]&gt; &#123;    return this.http.get(&#39;/api/tweets&#39;).map((resp: Response) =&gt; &#123;      console.log(resp.json());      var fetchedTweets = [];      for (let tweet of resp.json().data) &#123;        fetchedTweets.push(this.getTweetFromJson(tweet));      &#125;      return fetchedTweets as Array&lt;Tweet&gt;;    &#125;);  &#125;</code></pre><p>[ ] Update <code>feed.component.ts</code> to handle the observable</p><pre><code>this.feedService.getCurrentFeed().subscribe( (newTweets) =&gt; &#123;  console.log(newTweets);    this.tweets = newTweets;&#125;);</code></pre><p>[ ] Demo of changing our database file.</p><p>[ ] Next, we’ll update our service to handle posting a new tweet as a JSON object</p><pre><code>postNewTweet(tweetText: string) &#123;    let body = JSON.stringify(&#123;      body: tweetText, author: this.userService.getCurrentUser(),      date: new Date(), retweets: [], favorites: []    &#125;);    return this.http.post(&#39;/api/tweets&#39;, body).map(      (resp: Response) =&gt; &#123;        console.log(resp.json());        return this.getTweetFromJson(resp.json().data);      &#125;);  &#125;</code></pre><p>[ ] Update our feed.componoent.ts to subscribe to the create..</p><pre><code>OnNewTweet() &#123;    console.log(this.tweetText);    this.feedService.postNewTweet(this.tweetText).subscribe(      (newTweet : Tweet) =&gt; &#123;        console.log(newTweet);        this.tweets.unshift(newTweet);      &#125;);    this.tweetText = &#39;&#39;;  &#125;</code></pre><p>[ ] Finally, update our service to handle updates..</p><pre><code>updateTweet(tweet: Tweet) &#123;    let body = JSON.stringify(tweet);    let url = `/api/tweets/$&#123;tweet.id&#125;`;    return this.http.put(url, body).map(      (resp: Response) =&gt; &#123;        console.log(resp);        if (resp.status == 204) &#123;          console.log(&quot;Success. Yay!&quot;);        &#125;      &#125;);&#125;</code></pre><p>[ ] Update retweet and favorite routines in service with an update call</p><pre><code>this.updateTweet(tweet).subscribe(resp =&gt; console.log(resp));</code></pre><p>[ ] Let the winning flow!!!</p><p>[ ] Next up we’ll start looking into HTTP Error Handling  </p>]]></content>
    
    
    <summary type="html">&lt;p&gt;It’s finally time to introduce some Http CRUD implementation! Today on the show we use yesterday mock in-memory RESTful Http service to &lt;code&gt;get()&lt;/code&gt;, &lt;code&gt;post()&lt;/code&gt;, and &lt;code&gt;put()&lt;/code&gt; our way to remote data!&lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/ABNB02walbk&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] Implement our &lt;code&gt;getCurrentFeed()&lt;/code&gt; method&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;private getTweetFromJson(obj: Tweet): Tweet &amp;#123;
    return new Tweet(
      obj.id, obj.body, obj.author, obj.date, obj.retweets, obj.favorites)
  &amp;#125;

  getCurrentFeed(): Observable&amp;lt;Tweet[]&amp;gt; &amp;#123;

    return this.http.get(&amp;#39;/api/tweets&amp;#39;).map((resp: Response) =&amp;gt; &amp;#123;
      console.log(resp.json());
      var fetchedTweets = [];
      for (let tweet of resp.json().data) &amp;#123;
        fetchedTweets.push(this.getTweetFromJson(tweet));
      &amp;#125;
      return fetchedTweets as Array&amp;lt;Tweet&amp;gt;;
    &amp;#125;);

  &amp;#125;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Update &lt;code&gt;feed.component.ts&lt;/code&gt; to handle the observable&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;this.feedService.getCurrentFeed().subscribe( (newTweets) =&amp;gt; &amp;#123;
  console.log(newTweets);
    this.tweets = newTweets;
&amp;#125;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Demo of changing our database file.&lt;/p&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 14 - Using 3rd party JS with Angular CLI and Configuring an In-Memory RESTful endpoint</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/09/07/ng-day14-3rd-party-js-with-angular-cli-restful-inmemory-endpoint.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/09/07/ng-day14-3rd-party-js-with-angular-cli-restful-inmemory-endpoint.html</id>
    <published>2016-09-07T05:47:08.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>You’ll need to test your API - and your backend might not be built yet. But no matter! The Angular 2 team have your back with an InMemoryDbService Http RESTful database. </p><p>Learn how to configure it in today’s episode (or just learn about using 3rd party JS with the Angular CLI)</p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/c/FreshBytecode">Subscribe</a> to my <a href="https://www.youtube.com/c/FreshBytecode">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/QDKfRROoR-g" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] Install a 3rd party npm module to simulate REST (I’ve used a specific version since I know this one is compatible with Angular 2 RC5)</p><pre><code>npm install --save angular2-in-memory-web-api@0.0.17</code></pre><p>[ ] Update <code>angular-cli-build.js</code> to copy the npm over to dist</p><pre><code>  &#39;angular2-in-memory-web-api/*.+(js|js.map)&#39;</code></pre><p>[ ] Run an <code>ng build</code> to copy it over to <code>dist</code> and have a look </p><p>[ ] Update <code>system-config.ts</code> - but only in the top section of the file</p><pre><code>/** Map relative paths to URLs. */const map: any = &#123;  &#39;angular2-in-memory-web-api&#39; : &#39;vendor/angular2-in-memory-web-api&#39;&#125;;/** User packages configuration. */const packages: any = &#123;  &#39;angular2-in-memory-web-api&#39;: &#123;        main: &#39;./index.js&#39;,        defaultExtension: &#39;js&#39;   &#125;&#125;;</code></pre><p>[ ] Now we import the actual classes into our <code>app\app.module.ts</code> </p><pre><code>// Imports for loading &amp; configuring the in-memory web apiimport &#123; InMemoryWebApiModule &#125; from &#39;angular2-in-memory-web-api&#39;;import &#123; MockDatabaseService &#125;  from &#39;./mock.database.service&#39;;    imports: [ BrowserModule, FormsModule, routing, HttpModule,    InMemoryWebApiModule.forRoot(MockDatabaseService, &#123;         delay: 100,  rootPath: &#39;api/&#39;    &#125;) ],</code></pre><p>[ ] Implement our <code>mock.database.service.ts</code> method</p><pre><code>import &#123; InMemoryDbService &#125; from &#39;angular2-in-memory-web-api&#39;;import &#123; Tweet &#125; from &#39;./tweet&#39;;export class MockDatabaseService implements InMemoryDbService &#123;  createDb() &#123;    let friends = [       &quot;Mary&quot;, &quot;Joe&quot;, &quot;Karen&quot;, &quot;Phil&quot;, &quot;Toni&quot;     ];    let tweets = [      new Tweet(1, &#39;Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.&#39;, &#39;Glen&#39;, new Date(), [&#39;Joe&#39;], []),      new Tweet(2, &#39;Measuring programming progress by lines of code is like measuring aircraft building progress by weight&#39;, &#39;Joe&#39;, new Date(), [], [&#39;Mary&#39;]),      new Tweet(3, &#39;Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.&#39;, &#39;Mary&#39;, new Date(), [&#39;Glen&#39;], [&#39;Mary&#39;]),      new Tweet(4, &#39;People think that computer science is the art of geniuses but the actual reality is the opposite, just many people doing things that build on each other, like a wall of mini stones&#39;, &#39;Glen&#39;, new Date(), [&#39;Joe&#39;, &#39;Mary&#39;], []),      new Tweet(5, &#39;You can’t have great software without a great team, and most software teams behave like dysfunctional families.&#39;, &#39;Joe&#39;, new Date(), [], [&#39;Mary&#39;, &#39;Glen&#39;]),    ];    return &#123; &#39;tweets&#39; : tweets, &#39;friends&#39; : friends &#125;;  &#125;&#125;</code></pre><p>[ ] Update the Tweet constructor to handle that <code>id</code> field</p><pre><code>constructor(public id : number, public body: string, public author: string, public date: Date, public retweets: Array&lt;string&gt;, public favorites: Array&lt;string&gt;)</code></pre><p>[ ] Fix any code that the new <code>id</code> field on Tweets breaks</p><p>[ ] Demo that direct URL routing is not messed with</p><p>[ ] Demo that you can debug into your new class&#x2F;api</p><p>[ ] Run it and celebrate the win!</p><p>[ ] Next up we’ll start looking into CRUD http  </p>]]></content>
    
    
    <summary type="html">&lt;p&gt;You’ll need to test your API - and your backend might not be built yet. But no matter! The Angular 2 team have your back with an InMemoryDbService Http RESTful database. &lt;/p&gt;
&lt;p&gt;Learn how to configure it in today’s episode (or just learn about using 3rd party JS with the Angular CLI)&lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/QDKfRROoR-g&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] Install a 3rd party npm module to simulate REST (I’ve used a specific version since I know this one is compatible with Angular 2 RC5)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;npm install --save angular2-in-memory-web-api@0.0.17
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Update &lt;code&gt;angular-cli-build.js&lt;/code&gt; to copy the npm over to dist&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  &amp;#39;angular2-in-memory-web-api/*.+(js|js.map)&amp;#39;
&lt;/code&gt;&lt;/pre&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 13 - Introducing Http and Observables</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/09/05/ng-day13-http.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/09/05/ng-day13-http.html</id>
    <published>2016-09-05T21:03:01.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>It’s finally time to introduce some Http action into our app by fetching our Friends in async! Along the way we’ll learn about Observables.</p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/c/FreshBytecode">Subscribe</a> to my <a href="https://www.youtube.com/c/FreshBytecode">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/Amrsr_jUl5A" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] Fix the friend component deprecation</p><pre><code>import &#123; FriendComponent &#125; from &#39;./friend&#39;;declarations: [ AppComponent, FeedComponent, MenuComponent, FriendsComponent, FriendComponent, MessagesComponent ],</code></pre><p>[ ] First, let’s import the Angular Http Module into <code>app.module.ts</code></p><pre><code>import &#123; HttpModule &#125;    from &#39;@angular/http&#39;;imports: [ BrowserModule, FormsModule, HttpModule, routing ],</code></pre><p>[ ] Create a static json file in <code>public/friends.json</code> to simulate our server and hold our users (note the “double” quotes) </p><pre><code>[ &quot;Glen&quot;, &quot;Joe&quot;, &quot;Mary&quot; ]</code></pre><p>[ ] Inject our http service into our <code>friend.service.ts</code></p><pre><code>import &#123; Http, Response  &#125;    from &#39;@angular/http&#39;;import &#123; Observable &#125; from &#39;rxjs&#39;;constructor(private userService: UserService, private http : Http) &#123; &#125;</code></pre><p>[ ] Implement our <code>getFriends()</code> method using <code>http.get()</code></p><pre><code>getFriends() : Observable&lt;string[]&gt; &#123;return this.http.get(&#39;/friends.json&#39;).          map((resp : Response) =&gt; resp.json() as string[]) ;&#125;</code></pre><p>[ ] Update the our <code>friends.component.ts</code> to subscribe to the Observable</p><pre><code>ngOnInit() &#123;    this.feedService.getFriends().subscribe((newFriends) =&gt; &#123;            this.friends = newFriends;             console.log(this.friends);     &#125;);&#125;</code></pre><p>[ ] Run it and celebrate the win!</p><p>[ ] Next up we’ll start looking into CRUD http  </p>]]></content>
    
    
    <summary type="html">&lt;p&gt;It’s finally time to introduce some Http action into our app by fetching our Friends in async! Along the way we’ll learn about Observables.&lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Amrsr_jUl5A&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] Fix the friend component deprecation&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import &amp;#123; FriendComponent &amp;#125; from &amp;#39;./friend&amp;#39;;

declarations: [ AppComponent, FeedComponent, MenuComponent, FriendsComponent, FriendComponent, MessagesComponent ],
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] First, let’s import the Angular Http Module into &lt;code&gt;app.module.ts&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import &amp;#123; HttpModule &amp;#125;    from &amp;#39;@angular/http&amp;#39;;

imports: [ BrowserModule, FormsModule, HttpModule, routing ],
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Create a static json file in &lt;code&gt;public/friends.json&lt;/code&gt; to simulate our server and hold our users (note the “double” quotes) &lt;/p&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 12 - Deep Linking in the Router</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/09/02/ng-day12-router-deep-linking.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/09/02/ng-day12-router-deep-linking.html</id>
    <published>2016-09-02T04:20:35.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>On Day 12 we turn the Angular 2 Router up to 11 by deep linking to specific friend in our friends component.</p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/c/FreshBytecode">Subscribe</a> to my <a href="https://www.youtube.com/c/FreshBytecode">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/rGJ8hEyUe-w" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] First, let’s implement our Friends Component</p><pre><code>import &#123; FeedService &#125; from &#39;../feed.service&#39;;friends = [ ];  constructor(private feedService : FeedService) &#123;   &#125;  ngOnInit() &#123;    this.friends = this.feedService.getFriends();    console.log(this.friends);  &#125;</code></pre><p>[ ] Implement our <code>getFriends()</code> method</p><pre><code>getFriends() : Array&lt;string&gt; &#123;    return [ &#39;Mary&#39;, &#39;Joe&#39;, &#39;Karen&#39;, &#39;Phil&#39;, &#39;Toni&#39; ];&#125;</code></pre><p>[ ] Update the view</p><pre><code>&lt;div class=&quot;ui comments&quot; *ngIf=&#39;friends.length&#39;&gt;  &lt;div class=&quot;comment&quot; *ngFor=&#39;let friend of friends&#39;&gt;    &lt;a class=&quot;avatar&quot;&gt;      &lt;img src=&quot;./avatars/&#123;&#123;friend.toLowerCase()&#125;&#125;.jpg&quot;&gt;    &lt;/a&gt;    &lt;div class=&quot;content&quot;&gt;      &lt;a class=&quot;author&quot;&gt;&#123;&#123;friend&#125;&#125;&lt;/a&gt;            &lt;div class=&quot;actions&quot;&gt;        &lt;a &gt;Details&lt;/a&gt;      &lt;/div&gt;    &lt;/div&gt;  &lt;/div&gt;&lt;/div&gt;&lt;div *ngIf=&#39;!friends.length&#39;&gt;  &lt;h2&gt;THere are not any friends here&lt;/h2&gt;&lt;/div&gt;</code></pre><p>[ ] Show the friends list</p><p>[ ] Let’s create a component for deep linking into our friends details</p><pre><code>ng g c friend</code></pre><p>[ ] Update our <code>app.routing.ts</code> to point to the new component</p><pre><code>import &#123; FriendComponent &#125; from &#39;./friend&#39;;&#123; path: &#39;friends/:friendId&#39;, component: FriendComponent &#125;,</code></pre><p>[ ] Implement the new component <code>friend.component.ts</code> logic to get params</p><pre><code>  friendId = &#39;&#39;;  constructor(private route : ActivatedRoute) &#123; &#125;  ngOnInit() &#123;    this.route.params.map(params =&gt; params[&#39;friendId&#39;]).subscribe((friendId) =&gt; &#123;      this.friendId = friendId;      console.log(friendId);    &#125;)  &#125;</code></pre><p>[ ] Update the <code>friend.component.html</code> view file to output the friend:</p><pre><code>&lt;h2&gt;  This friend is &#123;&#123; friendId &#125;&#125;&lt;/h2&gt;</code></pre><p>[ ] Update our router link in <code>feeds.component.html</code> to pass the parameters:</p><pre><code>routerLink=&quot;/friends/&#123;&#123;friend&#125;&#125;&quot;</code></pre><p>[ ] Run it and cheer!</p><p>[ ] Next up we’ll start looking into http for remote data fetching </p>]]></content>
    
    
    <summary type="html">&lt;p&gt;On Day 12 we turn the Angular 2 Router up to 11 by deep linking to specific friend in our friends component.&lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/rGJ8hEyUe-w&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] First, let’s implement our Friends Component&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import &amp;#123; FeedService &amp;#125; from &amp;#39;../feed.service&amp;#39;;

friends = [ ];

  constructor(private feedService : FeedService) &amp;#123; 

  &amp;#125;

  ngOnInit() &amp;#123;
    this.friends = this.feedService.getFriends();
    console.log(this.friends);
  &amp;#125;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Implement our &lt;code&gt;getFriends()&lt;/code&gt; method&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;getFriends() : Array&amp;lt;string&amp;gt; &amp;#123;

    return [ &amp;#39;Mary&amp;#39;, &amp;#39;Joe&amp;#39;, &amp;#39;Karen&amp;#39;, &amp;#39;Phil&amp;#39;, &amp;#39;Toni&amp;#39; ];

&amp;#125;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Update the view&lt;/p&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 11 - Router Essentials</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/09/01/ng-day11-router-intro.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/09/01/ng-day11-router-intro.html</id>
    <published>2016-09-01T07:02:39.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>It’s time to introduce you to the Angular Router and get our menu routing to the various components in our application.</p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/c/FreshBytecode">Subscribe</a> to my <a href="https://www.youtube.com/c/FreshBytecode">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/mZ_btp2tbK4" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] Let’s create a component for friends and messages</p><pre><code>ng g c messagesng g c friends</code></pre><p>[ ] Now we’ll create a routing file <code>app.routing.ts</code> to setup all our routes in the app</p><pre><code>import &#123; ModuleWithProviders &#125; from &#39;@angular/core&#39;;import &#123; Routes, RouterModule &#125; from &#39;@angular/router&#39;;import &#123; FeedComponent &#125; from &#39;./feed&#39;;import &#123; FriendsComponent &#125; from &#39;./friends&#39;;import &#123; MessagesComponent &#125; from &#39;./messages&#39;;const appRoutes: Routes = [  &#123; path: &#39;&#39;,  redirectTo: &#39;/feed&#39;,  pathMatch: &#39;full&#39;&#125;,  &#123; path: &#39;feed&#39;, component: FeedComponent &#125;,  &#123; path: &#39;friends&#39;, component: FriendsComponent &#125;,  &#123; path: &#39;messages&#39;, component: MessagesComponent &#125;,];export const appRoutingProviders: any[] = [];export const routing : ModuleWithProviders = RouterModule.forRoot(appRoutes); </code></pre><p>[ ] Tell our module about this new routes in <code>app.module.ts</code></p><pre><code>import &#123; routing,     appRoutingProviders &#125; from &#39;./app.routing&#39;;providers: [ UserService, FeedService, appRoutingProviders ],imports: [ BrowserModule, FormsModule, routing ],</code></pre><p>[ ] Then update our app component html in <code>app.component.html</code></p><pre><code>&lt;app-menu&gt;&lt;/app-menu&gt;&lt;router-outlet&gt;&lt;/router-outlet&gt;</code></pre><p>[ ] Then we’ll need to update our menu to link to these new routes in <code>menu.componont.html</code></p><pre><code>&lt;a class=&quot;item&quot; routerLink=&quot;/feed&quot; routerLinkActive=&quot;active&quot;&gt;    Home&lt;/a&gt;&lt;a class=&quot;item&quot; routerLink=&quot;/messages&quot; routerLinkActive=&quot;active&quot;&gt;    Messages&lt;/a&gt;&lt;a class=&quot;item&quot; routerLink=&quot;/friends&quot; routerLinkActive=&quot;active&quot;&gt;    Friends&lt;/a&gt;</code></pre><p>[ ] Run application and celebrate</p><p>[ ] Tomorrow we’ll deep-route our User names </p>]]></content>
    
    
    <summary type="html">&lt;p&gt;It’s time to introduce you to the Angular Router and get our menu routing to the various components in our application.&lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/c/FreshBytecode&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/mZ_btp2tbK4&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] Let’s create a component for friends and messages&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ng g c messages
ng g c friends
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Now we’ll create a routing file &lt;code&gt;app.routing.ts&lt;/code&gt; to setup all our routes in the app&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import &amp;#123; ModuleWithProviders &amp;#125; from &amp;#39;@angular/core&amp;#39;;
import &amp;#123; Routes, RouterModule &amp;#125; from &amp;#39;@angular/router&amp;#39;;
import &amp;#123; FeedComponent &amp;#125; from &amp;#39;./feed&amp;#39;;
import &amp;#123; FriendsComponent &amp;#125; from &amp;#39;./friends&amp;#39;;
import &amp;#123; MessagesComponent &amp;#125; from &amp;#39;./messages&amp;#39;;

const appRoutes: Routes = [
  &amp;#123; path: &amp;#39;&amp;#39;,  redirectTo: &amp;#39;/feed&amp;#39;,  pathMatch: &amp;#39;full&amp;#39;&amp;#125;,
  &amp;#123; path: &amp;#39;feed&amp;#39;, component: FeedComponent &amp;#125;,
  &amp;#123; path: &amp;#39;friends&amp;#39;, component: FriendsComponent &amp;#125;,
  &amp;#123; path: &amp;#39;messages&amp;#39;, component: MessagesComponent &amp;#125;,
];

export const appRoutingProviders: any[] = [

];

export const routing : ModuleWithProviders = RouterModule.forRoot(appRoutes); 
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Tell our module about this new routes in &lt;code&gt;app.module.ts&lt;/code&gt;&lt;/p&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 10 - The Refactor and Consolidate Episode</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/08/30/ng-day10-refactor-party.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/08/30/ng-day10-refactor-party.html</id>
    <published>2016-08-30T06:58:03.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Today we inject services into services, refactor business logic out of components, and introduce you to Plain Old TypeScript Objects. </p><p>It’s a major tech debt paydown! And we consolidate everything you’ve learned so far!</p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Subscribe</a> to my <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/_6_gM3aSJL8" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] Introduce a new tweet class</p><pre><code>ng g class tweet</code></pre><p>[ ] First we’ll create our tweet properties</p><pre><code>export class Tweet &#123;    public avatar;    constructor(public body : string, public author: string, public date: Date, public retweets: Array&lt;string&gt;, public favorites: Array&lt;string&gt;) &#123;        this.avatar = `$&#123;author&#125;.jpg`;    &#125;&#125;</code></pre><p>[ ] Then refactor our tweet array</p><pre><code>tweets = [    new Tweet(&#39;Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.&#39;, &#39;Glen&#39;, new Date(), [&#39;Joe&#39;],  []),        new Tweet(&#39;Measuring programming progress by lines of code is like measuring aircraft building progress by weight&#39;,&#39;Joe&#39;, new Date(),  [],  [&#39;Mary&#39;] ),    new Tweet(&#39;Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.&#39;, &#39;Mary&#39;,  new Date(),  [&#39;Glen&#39;],  [&#39;Mary&#39;]),    new Tweet(&#39;People think that computer science is the art of geniuses but the actual reality is the opposite, just many people doing things that build on each other, like a wall of mini stones&#39;,  &#39;Glen&#39;,  new Date(),  [&#39;Joe&#39;, &#39;Mary&#39;],  [] ),        new Tweet(&#39;You can’t have great software without a great team, and most software teams behave like dysfunctional families.&#39;,  &#39;Joe&#39;,  new Date(),  [],  [&#39;Mary&#39;, &#39;Glen&#39;] ),  ]</code></pre><p>[ ] Create a new feed service</p><pre><code>ng g s feed</code></pre><p>[ ] Then we’ll move all our logic out of our feed component and into feed service (injecting our <code>UserService</code> into our <code>FeedService</code></p><pre><code>private tweets = [    new Tweet(&#39;Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.&#39;, &#39;Glen&#39;, new Date(), [&#39;Joe&#39;],  []),        new Tweet(&#39;Measuring programming progress by lines of code is like measuring aircraft building progress by weight&#39;,&#39;Joe&#39;, new Date(),  [],  [&#39;Mary&#39;] ),    new Tweet(&#39;Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.&#39;, &#39;Mary&#39;,  new Date(),  [&#39;Glen&#39;],  [&#39;Mary&#39;]),    new Tweet(&#39;People think that computer science is the art of geniuses but the actual reality is the opposite, just many people doing things that build on each other, like a wall of mini stones&#39;,  &#39;Glen&#39;,  new Date(),  [&#39;Joe&#39;, &#39;Mary&#39;],  [] ),        new Tweet(&#39;You can’t have great software without a great team, and most software teams behave like dysfunctional families.&#39;,  &#39;Joe&#39;,  new Date(),  [],  [&#39;Mary&#39;, &#39;Glen&#39;] ),  ]  constructor(private userService : UserService) &#123;   &#125;  getCurrentFeed() : Array&lt;Tweet&gt; &#123;    return this.tweets;  &#125;  private isUserInCollection(collection : string[], userId : string) : boolean &#123;      return collection.indexOf(userId) != -1;  &#125;  postNewTweet(tweetText : string) &#123;    this.tweets.unshift(          new Tweet(tweetText, this.userService.getCurrentUser(), new Date(), [], [])        );  &#125;  reTweet(tweet : Tweet) &#123;    if (!this.isUserInCollection(tweet.retweets, this.userService.getCurrentUser())) &#123;      tweet.retweets.push(this.userService.getCurrentUser());    &#125;  &#125;  favoriteTweet(tweet : Tweet) &#123;    if (!this.isUserInCollection(tweet.favorites, this.userService.getCurrentUser())) &#123;      tweet.favorites.push(this.userService.getCurrentUser());    &#125;  &#125;</code></pre><p>[ ] Let’s inject our feed service into our Feed component</p><pre><code>import &#123; FeedService &#125; from &#39;../feed.service&#39;;import &#123; Tweet &#125; from &#39;../tweet&#39;;tweets = [];constructor(private userService : UserService, private feedService : FeedService) &#123; &#125;ngOnInit() &#123;this.tweets = this.feedService.getCurrentFeed();&#125;</code></pre><p>[ ] Implement our logic</p><pre><code>  OnFavorite(tweet) &#123;    this.feedService.favoriteTweet(tweet);  &#125;  OnRetweet(tweet) &#123;    this.feedService.reTweet(tweet);  &#125;  OnNewTweet() &#123;    console.log(this.tweetText);    this.feedService.postNewTweet(this.tweetText);    this.tweetText = &#39;&#39;;  &#125; </code></pre><p>[ ] Update our view</p><pre><code>liked: tweet.hasFavorited(userService.getCurrentUser())retweeted: tweet.hasRetweeted(userService.getCurrentUser())</code></pre><p>[ ] Enhance our Tweet class</p><pre><code>hasFavorited(userId : string) : boolean &#123;    return this.favorites.indexOf(userId) != -1;&#125;hasRetweeted(userId : string) : boolean &#123;    return this.retweets.indexOf(userId) != -1;&#125;</code></pre><p>[ ] Run application to fan hysteria. </p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Today we inject services into services, refactor business logic out of components, and introduce you to Plain Old TypeScript Objects. &lt;/p&gt;
&lt;p&gt;It’s a major tech debt paydown! And we consolidate everything you’ve learned so far!&lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/_6_gM3aSJL8&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;



&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] Introduce a new tweet class&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ng g class tweet
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] First we’ll create our tweet properties&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;export class Tweet &amp;#123;

    public avatar;

    constructor(public body : string, public author: string, public date: Date, public retweets: Array&amp;lt;string&amp;gt;, public favorites: Array&amp;lt;string&amp;gt;) &amp;#123;
        this.avatar = `$&amp;#123;author&amp;#125;.jpg`;
    &amp;#125;

&amp;#125;
&lt;/code&gt;&lt;/pre&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 9 - Services and Dependency Injection</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/08/29/ng-day9-services-dependency-injection.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/08/29/ng-day9-services-dependency-injection.html</id>
    <published>2016-08-29T02:59:37.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>The technical debt has been piling up fast in our FeedComponent. It’s time to refactor that business logic out into services - and today on the show we’ll teach you how to get started. </p><p>(Spoiler: If you’ve done any Spring or Guice or Java EE6+ - this will be a piece of cake!)</p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Subscribe</a> to my <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/-0xrD6UE2hE" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] If you’ve used Spring or @Inject, this is all super familiar!</p><p>[ ] First we’ll create a user service</p><pre><code>ng g s User</code></pre><p>[ ] Note the <code>@Injectable</code></p><p>[ ] Then we’ll implement a current user method</p><pre><code>getCurrentUser() : string &#123;    return &#39;Glen&#39;;  &#125;</code></pre><p>[ ] Let’s write a test for that service (using Jasmin)</p><pre><code>expect(service.getCurrentUser()).toBe(&#39;Glenz&#39;);</code></pre><p>[ ] Run the test</p><pre><code>ng test --build=false --watch=false </code></pre><p>[ ] Fix the test</p><p>[ ] Inject the UserService into the FeedComponent</p><pre><code>import &#123; UserService &#125; from &#39;../user.service&#39;;providers: [UserService],constructor(private userService : UserService) &#123; &#125;</code></pre><p>[ ] Replace all our backing component refs to ‘Glen’</p><p>[ ] Replace all our view component refs to ‘Glen’</p><p>[ ] Move the provides to the ng Module level</p><p>[ ] Talk about implications of exporting ngModule services</p><p>[ ] Cue Applause. Tomorrow we’ll tackle the FeedService</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;The technical debt has been piling up fast in our FeedComponent. It’s time to refactor that business logic out into services - and today on the show we’ll teach you how to get started. &lt;/p&gt;
&lt;p&gt;(Spoiler: If you’ve done any Spring or Guice or Java EE6+ - this will be a piece of cake!)&lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/-0xrD6UE2hE&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] If you’ve used Spring or @Inject, this is all super familiar!&lt;/p&gt;
&lt;p&gt;[ ] First we’ll create a user service&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ng g s User
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Note the &lt;code&gt;@Injectable&lt;/code&gt;&lt;/p&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 8 - Data Binding and ngModel</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/08/25/ng-day8-data-binding.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/08/25/ng-day8-data-binding.html</id>
    <published>2016-08-25T23:09:33.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>It’s finally here - the day we add a tweet input element and can actually post things to our timeline. </p><p>Let’s take a moment to brag:</p><p><img src="/glen/glen/images/2016/ngmodel-data-binding.gif" alt="Let the tweets flow!"></p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Subscribe</a> to my <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/XsdStDuH3A0" frameborder="0" allowfullscreen></iframe><p>Here’s the script so you can follow along at home:</p><p>[ ] First we’ll use the element markup</p><pre><code>&lt;form class=&quot;ui form&quot;&gt;  &lt;div class=&quot;field&quot;&gt;    &lt;label&gt;What&#39;s on your mind?&lt;/label&gt;    &lt;textarea name=&#39;body&#39; placeholder=&quot;Penny for your thoughts&quot; type=&quot;text&quot;&gt;&lt;/textarea&gt;  &lt;/div&gt;  &lt;button class=&quot;ui button primary&quot; type=&quot;button&quot;&gt;Tweet&lt;/button&gt;&lt;/form&gt;</code></pre><p>[ ] Then we’ll make a local variable that gives you access to the element in the template</p><pre><code>#mytext(click)=&#39;OnNewTweet(mytext)&#39;</code></pre><p>[ ] We’ll need a method to handle the new tweet</p><pre><code>OnNewTweet(myTweet) &#123;    console.log(myTweet.value);&#125;</code></pre><p>[ ] Need to add the forms module to the <code>app.module.ts</code></p><pre><code>import &#123; FormsModule &#125; from &#39;@angular/forms&#39;;imports: [ BrowserModule, FormsModule ],</code></pre><p>[ ] Binding to a backing property MVVM</p><pre><code>tweetText = &#39;&#39;;</code></pre><p>[ ] Add the ngModel directive - put the banana in the box </p><pre><code>[(ngModel)]=&#39;tweetText&#39;</code></pre><p>[ ] Change the OnNewTweet to take no args</p><pre><code>OnNewTweet() &#123;    this.tweets.unshift(      &#123; body: this.tweetText, author: &#39;Glen&#39;, avatar: &#39;glen.jpg&#39;, date: new Date(), retweets: [], favorites: [] &#125;    );    this.tweetText = &#39;&#39;;&#125;</code></pre><p>[ ] Live the dream!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;It’s finally here - the day we add a tweet input element and can actually post things to our timeline. &lt;/p&gt;
&lt;p&gt;Let’s take a moment to brag:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/ngmodel-data-binding.gif&quot; alt=&quot;Let the tweets flow!&quot;&gt;&lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/XsdStDuH3A0&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Here’s the script so you can follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] First we’ll use the element markup&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;form class=&amp;quot;ui form&amp;quot;&amp;gt;
  &amp;lt;div class=&amp;quot;field&amp;quot;&amp;gt;
    &amp;lt;label&amp;gt;What&amp;#39;s on your mind?&amp;lt;/label&amp;gt;
    &amp;lt;textarea name=&amp;#39;body&amp;#39; placeholder=&amp;quot;Penny for your thoughts&amp;quot; type=&amp;quot;text&amp;quot;&amp;gt;&amp;lt;/textarea&amp;gt;
  &amp;lt;/div&amp;gt;

  &amp;lt;button class=&amp;quot;ui button primary&amp;quot; type=&amp;quot;button&amp;quot;&amp;gt;Tweet&amp;lt;/button&amp;gt;
&amp;lt;/form&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Then we’ll make a local variable that gives you access to the element in the template&lt;/p&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 7 - Properties and Styles</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/08/25/ng-day7-properties.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/08/25/ng-day7-properties.html</id>
    <published>2016-08-25T00:59:20.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Today on the show we investigate Angular 2 [property] syntax - and also explore the wonders of per-component styling. </p><p><img src="/glen/glen/images/2016/ng-events-properties.gif" alt="Now with click events and dynamic styles!"></p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Subscribe</a> to my <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/Iazb3EedFpg" frameborder="0" allowfullscreen></iframe><p>Here’s the script to follow along at home:</p><p>[ ] You can hack DOM properties directly with [prop] syntax (not the quotes inside the quotes)</p><pre><code>[style.color]=&#39;&quot;red&quot;&#39;</code></pre><p>[ ] You can also do per-component styling that won’t clash with the rest of your layout:</p><pre><code>.like &#123;    color: red !important;&#125; .retweet &#123;    color: red !important;&#125;</code></pre><p>[ ] But we want that to be conditional, so we’ll change the classes</p><pre><code>.liked &#123;    color: red !important;&#125; .retweeted &#123;    color: red !important;&#125;</code></pre><p>[ ] Be good to do this conditionally using <code>ngClass</code> directive</p><pre><code>[ngClass]=&#39;&#123; retweeted: isUserInCollection(tweet.retweets, &quot;Glen&quot;) &#125;&#39;[ngClass]=&#39;&#123; retweeted: isUserInCollection(tweet.retweets, &quot;Glen&quot;) &#125;&#39;</code></pre><p>[ ] Cheer our awesomeness. We’ve learned about (events) and [properties]. Tomorrow, the textbox cometh!</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Today on the show we investigate Angular 2 [property] syntax - and also explore the wonders of per-component styling. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/ng-events-properties.gif&quot; alt=&quot;Now with click events and dynamic styles!&quot;&gt;&lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Iazb3EedFpg&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Here’s the script to follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] You can hack DOM properties directly with [prop] syntax (not the quotes inside the quotes)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[style.color]=&amp;#39;&amp;quot;red&amp;quot;&amp;#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] You can also do per-component styling that won’t clash with the rest of your layout:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.like &amp;#123;
    color: red !important;
&amp;#125; 

.retweet &amp;#123;
    color: red !important;
&amp;#125;
&lt;/code&gt;&lt;/pre&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 6 - Events</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/08/24/ng-day6-events.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/08/24/ng-day6-events.html</id>
    <published>2016-08-24T06:56:32.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>Today we investigate the wonders of (click) events and catching them in our backing component. We’ll be tweeted and favoriting up a storm. </p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Subscribe</a> to my <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out.</p><iframe width="560" height="315" src="https://www.youtube.com/embed/Yog8B7Us1SY" frameborder="0" allowfullscreen></iframe><p>Here’s the script to follow along at home:</p><p>[ ] First we’re going to implement our Favorite and Retweet buttons using (click) Events</p><pre><code>(click)=&#39;OnFavorite(tweet)&#39;(click)=&#39;OnRetweet(tweet)&#39;</code></pre><p>[ ] Implement the click handlers too</p><pre><code>OnFavorite(tweet) &#123;    tweet.favorites.push(&#39;Glen&#39;);&#125;OnRetweet(tweet) &#123;    tweet.retweets.push(&#39;Glen&#39;);&#125;</code></pre><p>[ ] Stop double-adds? Be great to do it “properly” with a Tweet object method</p><pre><code>isUserInCollection(collection : string[], userId : string) : boolean &#123;    return collection.indexOf(userId) != -1;&#125;OnFavorite(tweet) &#123;    if (!this.isUserInCollection(tweet.favorites, &#39;Glen&#39;)) &#123;        tweet.favorites.push(&#39;Glen&#39;);    &#125;&#125;OnRetweet(tweet) &#123;    if (!this.isUserInCollection(tweet.retweets, &#39;Glen&#39;)) &#123;        tweet.retweets.push(&#39;Glen&#39;);    &#125;&#125;</code></pre><p>[ ] Demonstrate only adding yourself once</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;Today we investigate the wonders of (click) events and catching them in our backing component. We’ll be tweeted and favoriting up a storm. &lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out.&lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/Yog8B7Us1SY&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;Here’s the script to follow along at home:&lt;/p&gt;
&lt;p&gt;[ ] First we’re going to implement our Favorite and Retweet buttons using (click) Events&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(click)=&amp;#39;OnFavorite(tweet)&amp;#39;

(click)=&amp;#39;OnRetweet(tweet)&amp;#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Implement the click handlers too&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;OnFavorite(tweet) &amp;#123;
    tweet.favorites.push(&amp;#39;Glen&amp;#39;);
&amp;#125;

OnRetweet(tweet) &amp;#123;
    tweet.retweets.push(&amp;#39;Glen&amp;#39;);
&amp;#125;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[ ] Stop double-adds? Be great to do it “properly” with a Tweet object method&lt;/p&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 5 - ngIf, ngFor and a real timeline</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/08/23/ng-day5-timeline.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/08/23/ng-day5-timeline.html</id>
    <published>2016-08-23T01:33:06.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>In today’s episode, we finally implement a nice looking timeline! Along the way we learn about <a href="https://angular.io/docs/ts/latest/api/common/index/NgFor-directive.html">ngFor</a>, <a href="https://angular.io/docs/ts/latest/api/common/index/NgIf-directive.html">ngIf</a>, and the <a href="https://angular.io/docs/ts/latest/api/common/index/DatePipe-class.html">Date Pipe</a>.</p><p><img src="/glen/glen/images/2016/ng-timeline.png" alt="Our Twitter Timeline is taking shape!"></p><p>Here’s some cool resources to checkout from today’s show:</p><ul><li><a href="http://semantic-ui.com/views/comment.html">That Comment Layout</a> from Semantic UI</li><li><a href="http://uifaces.com/authorized">Free Icons for Twitter Templates</a></li></ul><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Subscribe</a> to my <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out. </p><iframe width="560" height="315" src="https://www.youtube.com/embed/G45-j6tC9W8" frameborder="0" allowfullscreen></iframe><p>Here’s the cheat sheet to follow along at home…</p><p>[ ] Copy our <a href="http://uifaces.com/authorized">avatars</a> into <code>public/avatars</code></p><p>[ ] First of all add an Array of Objects&#x2F;Maps to <code>timeline.component.ts</code> to hold our tweets:</p><pre><code>tweets = [     &#123; body: &#39;Some tweet text&#39;, author: &#39;Glen&#39; &#125;,    &#123; body: &#39;Some other text&#39;, author: &#39;Karen&#39; &#125;,]</code></pre><p>[ ] Put in our layout code from <a href="http://semantic-ui.com/views/comment.html">Semantic UI</a> into <code>timeline.component.html</code></p><pre><code>&lt;div class=&quot;ui comments&quot;&gt;  &lt;div class=&quot;comment&quot; *ngFor=&#39;let tweet of tweets&#39;&gt;    &lt;a class=&quot;avatar&quot;&gt;      &lt;img src=&quot;/avatars/&#123;&#123;tweet.avatar&#125;&#125;&quot;&gt;    &lt;/a&gt;    &lt;div class=&quot;content&quot;&gt;      &lt;a class=&quot;author&quot;&gt;&#123;&#123;tweet.author&#125;&#125;&lt;/a&gt;      &lt;div class=&quot;metadata&quot;&gt;        &lt;span class=&quot;date&quot;&gt; &#123;&#123;tweet.date  &#125;&#125;&lt;/span&gt;      &lt;/div&gt;      &lt;div class=&quot;text&quot;&gt;        &#123;&#123;tweet.body&#125;&#125;      &lt;/div&gt;      &lt;div class=&quot;actions&quot;&gt;        &lt;a class=&quot;reply&quot;&gt;Reply&lt;/a&gt;        &lt;a class=&quot;like&quot;&gt;          &lt;i class=&quot;like icon&quot;&gt;&lt;/i&gt; &#123;&#123;tweet.favorites.length&#125;&#125; Favourites        &lt;/a&gt;        &lt;a class=&quot;retweet&quot;&gt;          &lt;i class=&quot;retweet icon&quot;&gt;&lt;/i&gt; &#123;&#123;tweet.retweets.length&#125;&#125; Retweets        &lt;/a&gt;      &lt;/div&gt;    &lt;/div&gt;  &lt;/div&gt;&lt;/div&gt;</code></pre><p>[ ] Then fill it out with some real data</p><pre><code>tweets = [    &#123; body: &#39;Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live.&#39;, author: &#39;Glen&#39;, avatar: &#39;glen.jpg&#39;, date: new Date(), retweets: [ &#39;Joe&#39;], favorites: [] &#125;,    &#123; body: &#39;Measuring programming progress by lines of code is like measuring aircraft building progress by weight&#39;, author: &#39;Joe&#39;, avatar: &#39;joe.jpg&#39;, date: new Date(), retweets: [], favorites: [&#39;Mary&#39;] &#125;,    &#123; body: &#39;Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.&#39;, author: &#39;Mary&#39;, avatar: &#39;mary.jpg&#39;, date: new Date(), retweets: [&#39;Glen&#39;], favorites: [&#39;Mary&#39;] &#125;,    &#123; body: &#39;People think that computer science is the art of geniuses but the actual reality is the opposite, just many people doing things that build on each other, like a wall of mini stones&#39;, author: &#39;Glen&#39;, avatar: &#39;glen.jpg&#39;, date: new Date(), retweets: [ &#39;Joe&#39;, &#39;Mary&#39;], favorites: [] &#125;,    &#123; body: &#39;You can’t have great software without a great team, and most software teams behave like dysfunctional families.&#39;, author: &#39;Joe&#39;, avatar: &#39;joe.jpg&#39;, date: new Date(), retweets: [], favorites: [&#39;Mary&#39;, &#39;Glen&#39;] &#125;,  ]</code></pre><p>[ ] Put in our conditional show of tweets or “No tweets today” using <code>*ngIf</code></p><pre><code>&lt;div class=&quot;ui comments&quot; *ngIf=&#39;tweets.length&#39;&gt; &lt;/div&gt;&lt;div *ngIf=&#39;!tweets.length&#39;&gt;  &lt;h2&gt;No tweets today.&lt;/h2&gt;&lt;/div&gt;</code></pre><p>[ ] Put in our pipe for the date to get a nicer layout</p><pre><code>&#123;&#123;tweet.date | date:'h:mm:ss dd/mm/yy' &#125;&#125;</code></pre><p>[ ]  Deploy to crowd applause</p>]]></content>
    
    
    <summary type="html">&lt;p&gt;In today’s episode, we finally implement a nice looking timeline! Along the way we learn about &lt;a href=&quot;https://angular.io/docs/ts/latest/api/common/index/NgFor-directive.html&quot;&gt;ngFor&lt;/a&gt;, &lt;a href=&quot;https://angular.io/docs/ts/latest/api/common/index/NgIf-directive.html&quot;&gt;ngIf&lt;/a&gt;, and the &lt;a href=&quot;https://angular.io/docs/ts/latest/api/common/index/DatePipe-class.html&quot;&gt;Date Pipe&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/glen/glen/images/2016/ng-timeline.png&quot; alt=&quot;Our Twitter Timeline is taking shape!&quot;&gt;&lt;/p&gt;
&lt;p&gt;Here’s some cool resources to checkout from today’s show:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://semantic-ui.com/views/comment.html&quot;&gt;That Comment Layout&lt;/a&gt; from Semantic UI&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://uifaces.com/authorized&quot;&gt;Free Icons for Twitter Templates&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out. &lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/G45-j6tC9W8&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;Here’s the cheat sheet to follow along at home…&lt;/p&gt;
&lt;p&gt;[ ] Copy our &lt;a href=&quot;http://uifaces.com/authorized&quot;&gt;avatars&lt;/a&gt; into &lt;code&gt;public/avatars&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;[ ] First of all add an Array of Objects&amp;#x2F;Maps to &lt;code&gt;timeline.component.ts&lt;/code&gt; to hold our tweets:&lt;/p&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 4 - Migrate to RC5</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/08/22/ng-day4-migrate-rc5.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/08/22/ng-day4-migrate-rc5.html</id>
    <published>2016-08-22T02:45:50.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>In today’s episode, we’re moving from RC4 to RC5. RC5 is reported to be the last of the breaking changes before Go-Live, so it’s worth upgrading.</p><p>Here’s some cool resources to checkout for further deep diving on the RC5 migration:</p><ul><li><a href="https://angular.io/docs/ts/latest/cookbook/rc4-to-rc5.html">The Official Guide</a></li><li><a href="https://www.barbarianmeetscoding.com/blog/2016/08/13/updating-your-angular-2-app-from-rc4-to-rc5-a-practical-guide/">A Practical Guide</a> - cool deep-dive from the field</li></ul><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Subscribe</a> to my <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out. </p><iframe width="560" height="315" src="https://www.youtube.com/embed/V4sHxwVzUCY" frameborder="0" allowfullscreen></iframe><p>Here’s the cheat sheet to follow along at home…</p><p>[ ] Update <code>package.json</code> with rc5 links (Ctrl-D is your friend)</p><ul><li>@angular stuff rc5</li><li>forms to 0.3.0</li><li>router to rc.1</li></ul><p>[ ] Do an <code>npm install</code> to fetch the new packages<br>[ ] Run <code>ng serve</code> to prove the backward compatible action is working<br>[ ] Add <code>app.module.ts</code> in root.</p><pre><code>import &#123; NgModule &#125; from &#39;@angular/core&#39;;import &#123; BrowserModule &#125; from &#39;@angular/platform-browser&#39;;import &#123; AppComponent &#125; from &#39;./app.component&#39;;@NgModule(&#123;    declarations: [ AppComponent ],    providers: [ ],    imports: [ BrowserModule ],    bootstrap: [ AppComponent ]&#125;)export class AppModule &#123; &#125;</code></pre><p>[ ]  Updated your bootstrap in <code>main.ts</code></p><pre><code>import &#123; platformBrowserDynamic &#125; from &#39;@angular/platform-browser-dynamic&#39;;import &#123; AppModule &#125; from &#39;./app/app.module&#39;;platformBrowserDynamic().bootstrapModule(AppModule);</code></pre><p>[ ] Move your directives into declarations </p><pre><code>import &#123; MenuComponent &#125; from &#39;./menu&#39;;import &#123; FeedComponent &#125; from &#39;./feed&#39;;@NgModule(&#123;    declarations: [ AppComponent, FeedComponent, MenuComponent ],</code></pre><p>[ ] Remove all your providers and declarations in <code>app.componont.ts</code></p>]]></content>
    
    
    <summary type="html">&lt;p&gt;In today’s episode, we’re moving from RC4 to RC5. RC5 is reported to be the last of the breaking changes before Go-Live, so it’s worth upgrading.&lt;/p&gt;
&lt;p&gt;Here’s some cool resources to checkout for further deep diving on the RC5 migration:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://angular.io/docs/ts/latest/cookbook/rc4-to-rc5.html&quot;&gt;The Official Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.barbarianmeetscoding.com/blog/2016/08/13/updating-your-angular-2-app-from-rc4-to-rc5-a-practical-guide/&quot;&gt;A Practical Guide&lt;/a&gt; - cool deep-dive from the field&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out. &lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/V4sHxwVzUCY&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;



&lt;p&gt;Here’s the cheat sheet to follow along at home…&lt;/p&gt;
&lt;p&gt;[ ] Update &lt;code&gt;package.json&lt;/code&gt; with rc5 links (Ctrl-D is your friend)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;@angular stuff rc5&lt;/li&gt;
&lt;li&gt;forms to 0.3.0&lt;/li&gt;
&lt;li&gt;router to rc.1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;[ ] Do an &lt;code&gt;npm install&lt;/code&gt; to fetch the new packages&lt;br&gt;[ ] Run &lt;code&gt;ng serve&lt;/code&gt; to prove the backward compatible action is working&lt;br&gt;[ ] Add &lt;code&gt;app.module.ts&lt;/code&gt; in root.&lt;/p&gt;</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
  <entry>
    <title>Angular 2 Challenge Day 3 - Components within Components</title>
    <link href="http://blogs.bytecode.com.au/glen/2016/08/20/ng-day3-components-in-components.html"/>
    <id>http://blogs.bytecode.com.au/glen/2016/08/20/ng-day3-components-in-components.html</id>
    <published>2016-08-20T00:06:24.000Z</published>
    <updated>2022-12-28T05:51:04.598Z</updated>
    
    <content type="html"><![CDATA[<p>In today’s episode, we’re moving from “page thinking” to “component thinking” as we explore nesting Angular components within one another.</p><p>It’s also time to start getting our Twitter vibe happening using some magic stuff from <a href="http://semantic-ui.com/">Semantic UI</a></p><p>You can always grab tagged source code on the <a href="https://github.com/glenasmith/twit-ng">GitHub repo</a> which will be tagged day1, day2, etc.</p><p>You can <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Subscribe</a> to my <a href="https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w">Fresh Bytecode</a> channel for regular Java&#x2F;Web-related screencasts, or if you’re just into Angular, checkout the <a href="https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn">YouTube Playlist</a> where I update all the episodes in this series as they come out. </p><iframe width="560" height="315" src="https://www.youtube.com/embed/SUUeOwq-o-A" frameborder="0" allowfullscreen></iframe><p>Here’s the cheat sheet to follow along at home…</p><p>[ ] Twitter - in component terms rather than page terms<br>[ ] <code>ng generate component menu</code><br>[ ] Add the <code>&lt;app-menu&gt;&lt;/app-menu&gt;</code> markup<br>[ ] <code>import &#123; MenuComponent &#125; from &#39;./menu&#39;;</code><br>[ ] <code>directives: [ MenuComponent ]</code><br>[ ] Rinse and repeat for Feed<br>[ ] Add layout magic from <a href="http://semantic-ui.com/collections/menu.html">Semantic Menus</a></p><p>Here are the CDN links for Semantic UI that I used:</p><pre><code>&lt;link rel=&quot;stylesheet&quot; href=&quot;https://cdn.jsdelivr.net/semantic-ui/2.2.2/semantic.min.css&quot; &gt;&lt;script src=&quot;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.js&quot;&gt;&lt;/script&gt;&lt;script src=&quot;https://cdn.jsdelivr.net/semantic-ui/2.2.2/semantic.min.js&quot;&gt;&lt;/script&gt;</code></pre>]]></content>
    
    
    <summary type="html">&lt;p&gt;In today’s episode, we’re moving from “page thinking” to “component thinking” as we explore nesting Angular components within one another.&lt;/p&gt;
&lt;p&gt;It’s also time to start getting our Twitter vibe happening using some magic stuff from &lt;a href=&quot;http://semantic-ui.com/&quot;&gt;Semantic UI&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can always grab tagged source code on the &lt;a href=&quot;https://github.com/glenasmith/twit-ng&quot;&gt;GitHub repo&lt;/a&gt; which will be tagged day1, day2, etc.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Subscribe&lt;/a&gt; to my &lt;a href=&quot;https://www.youtube.com/channel/UChOgnDhsjo_8UGhPQH8tH1w&quot;&gt;Fresh Bytecode&lt;/a&gt; channel for regular Java&amp;#x2F;Web-related screencasts, or if you’re just into Angular, checkout the &lt;a href=&quot;https://www.youtube.com/playlist?list=PLix-OafSjpFmq9K8eItC6bFSgz-732Rkn&quot;&gt;YouTube Playlist&lt;/a&gt; where I update all the episodes in this series as they come out. &lt;/p&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/SUUeOwq-o-A&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;

&lt;p&gt;Here’s the cheat sheet to follow along at home…&lt;/p&gt;
&lt;p&gt;[ ] Twitter - in component terms rather than page terms&lt;br&gt;[ ] &lt;code&gt;ng generate component menu&lt;/code&gt;&lt;br&gt;[ ] Add the &lt;code&gt;&amp;lt;app-menu&amp;gt;&amp;lt;/app-menu&amp;gt;&lt;/code&gt; markup&lt;br&gt;[ ] &lt;code&gt;import &amp;#123; MenuComponent &amp;#125; from &amp;#39;./menu&amp;#39;;&lt;/code&gt;&lt;br&gt;[ ] &lt;code&gt;directives: [ MenuComponent ]&lt;/code&gt;&lt;br&gt;[ ] Rinse and repeat for Feed&lt;br&gt;[ ] Add layout magic from &lt;a href=&quot;http://semantic-ui.com/collections/menu.html&quot;&gt;Semantic Menus&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here are the CDN links for Semantic UI that I used:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://cdn.jsdelivr.net/semantic-ui/2.2.2/semantic.min.css&amp;quot; &amp;gt;

&amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;

&amp;lt;script src=&amp;quot;https://cdn.jsdelivr.net/semantic-ui/2.2.2/semantic.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
</summary>
    
    
    
    
    <category term="Java" scheme="http://blogs.bytecode.com.au/glen/tags/Java/"/>
    
    <category term="JavaScript" scheme="http://blogs.bytecode.com.au/glen/tags/JavaScript/"/>
    
    <category term="Angular" scheme="http://blogs.bytecode.com.au/glen/tags/Angular/"/>
    
  </entry>
  
</feed>
