<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:media="http://search.yahoo.com/mrss/"><channel><title><![CDATA[Steve Michelotti]]></title><description><![CDATA[Hi, I'm Steve Michelotti. I'm a passionate technologist, create courses for Pluralsight, and speak at developer events on web and cloud technologies]]></description><link>https://stevemichelotti.com/</link><image><url>https://stevemichelotti.com/favicon.png</url><title>Steve Michelotti</title><link>https://stevemichelotti.com/</link></image><generator>Ghost 6.26</generator><lastBuildDate>Thu, 09 Apr 2026 08:33:22 GMT</lastBuildDate><atom:link href="https://stevemichelotti.com/rss/" rel="self" type="application/rss+xml"/><ttl>60</ttl><item><title><![CDATA[Optimizing Windows Terminal for Sovereign Clouds]]></title><description><![CDATA[<p>I work with Azure sovereign clouds (specifically <a href="https://azure.microsoft.com/en-us/global-infrastructure/government/?ref=stevemichelotti.com">Azure Government</a>) every day, and I spend a lot of time using the <a href="https://docs.microsoft.com/en-us/cli/azure/?ref=stevemichelotti.com">Azure CLI</a> inside of <a href="https://docs.microsoft.com/en-us/windows/terminal/?ref=stevemichelotti.com">Windows Terminal</a>. I was recently on an episode of <a href="https://www.youtube.com/watch?v=nhT0wR1RC-o&amp;ref=stevemichelotti.com">Azure Friday talking about Azure Government</a> with <a href="https://www.hanselman.com/blog/my-ultimate-powershell-prompt-with-oh-my-posh-and-the-windows-terminal?ref=stevemichelotti.com">Scott Hanselman</a>, which included a demo using the Azure CLI</p>]]></description><link>https://stevemichelotti.com/optimizing-windows-terminal-for-sovereign-clouds/</link><guid isPermaLink="false">6151b7499a16b40048ee329b</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Mon, 27 Sep 2021 18:58:25 GMT</pubDate><content:encoded><![CDATA[<p>I work with Azure sovereign clouds (specifically <a href="https://azure.microsoft.com/en-us/global-infrastructure/government/?ref=stevemichelotti.com">Azure Government</a>) every day, and I spend a lot of time using the <a href="https://docs.microsoft.com/en-us/cli/azure/?ref=stevemichelotti.com">Azure CLI</a> inside of <a href="https://docs.microsoft.com/en-us/windows/terminal/?ref=stevemichelotti.com">Windows Terminal</a>. I was recently on an episode of <a href="https://www.youtube.com/watch?v=nhT0wR1RC-o&amp;ref=stevemichelotti.com">Azure Friday talking about Azure Government</a> with <a href="https://www.hanselman.com/blog/my-ultimate-powershell-prompt-with-oh-my-posh-and-the-windows-terminal?ref=stevemichelotti.com">Scott Hanselman</a>, which included a demo using the Azure CLI with Azure Government. After the recording was over, Scott and I were chatting and he mentioned a couple of suggestions to me that might enhance my (already heavily customized) Windows Terminal experience when working with sovereign clouds. Specifically his ideas were:</p><ul><li>Leverage the <a href="https://ohmyposh.dev/docs/az?ref=stevemichelotti.com">Oh My Post Azure segment</a> to show my current Azure CLI session</li><li>Dynamically change my terminal background image to make it more obvious which cloud I was currently connected to (i.e., Azure public vs. Azure Gov)</li></ul><p>While those two things sounded great, neither was precisely supported &quot;out of the box&quot;. (Side note: before I start diving into Oh My Posh in this post, I highly recommend <a href="https://ohmyposh.dev/?ref=stevemichelotti.com">checking out their docs</a> for those who are not familiar).</p><h2 id="oh-my-posh-azure-segment">Oh My Posh Azure Segment</h2><p>The Oh My Posh Azure Segment will contextually display information about your current Azure CLI session like this:</p><!--kg-card-begin: markdown--><p><img src="https://stevemichelotti.blob.core.windows.net/images/az-segment-default.png" alt="Azure Segment default" loading="lazy"></p>
<!--kg-card-end: markdown--><p>This segment (in light blue above) shows me the currently logged in user and the name of my Azure subscription. However, it doesn&apos;t tell me <strong><em>which</em> </strong>Azure cloud I&apos;m logged into. Yes, it&apos;s pretty easy to know which usernames I use for Azure public vs. Azure Gov, but it&apos;s not <em><strong>obvious</strong></em>. Switching between Azure and Azure Government using the Azure CLI is done simply using these CLI commands:</p><!--kg-card-begin: markdown--><pre><code class="language-powershell">az cloud set --name AzureCloud         # sets to Azure
az cloud set --name AzureUSGovernment  # sets to Azure Gov
</code></pre>
<!--kg-card-end: markdown--><p>The first challenge is that the environment name wasn&apos;t supported by the Oh My Posh Az segment. After a couple of emails with <a href="https://github.com/sponsors/JanDeDobbeleer?ref=stevemichelotti.com">Jan De Dobbeleer</a> (of Oh My Posh fame), and a blazingly fast turn-around on Jan&apos;s part for a <a href="https://github.com/JanDeDobbeleer/oh-my-posh/releases/tag/v5.0.0?ref=stevemichelotti.com">new release</a>, the Az segment was updated to use templating so that <em>any</em> property in the <strong><code>az account show</code></strong> command could be used. With this ability, my Az segment configuration now looks like this:</p><!--kg-card-begin: markdown--><pre><code class="language-json">{
  &quot;type&quot;: &quot;az&quot;,
  &quot;style&quot;: &quot;powerline&quot;,
  &quot;powerline_symbol&quot;: &quot;\uE0B0&quot;,
  &quot;foreground&quot;: &quot;#000000&quot;,
  &quot;background&quot;: &quot;#9ec3f0&quot;,
  &quot;properties&quot;: {
    &quot;template&quot;: &quot;{{.EnvironmentName}} | {{.Name}}&quot;,
    &quot;prefix&quot;: &quot; \uFD03 &quot;,
    &quot;include_folders&quot;: [
      &quot;*\\\\az&quot;
    ]
  }
},
</code></pre>
<!--kg-card-end: markdown--><p>Which results in a terminal prompt that looks like this:</p><!--kg-card-begin: markdown--><p><img src="https://stevemichelotti.blob.core.windows.net/images/az-segment-with-env.png" alt="Azure Segment with env" loading="lazy"></p>
<!--kg-card-end: markdown--><p>Now I can configure this to show whatever I want - which in this case is to show the environment name (<code>AzureUSGovernment</code> or <code>AzureCloud</code>) followed by the current subscription name.</p><p>One other thing to note is that I&apos;m using the <code>include_folders</code> property in my configuration above. This is because segments like this can cause a little bit of a delay since they&apos;re invoking an az cli command every time it renders a prompt. So I wanted a quick way to turn the segment on/off on demand without having to mess with my oh-my-posh configuration. This enables me to just <code>cd ~/az</code> anytime I want to turn this segment on.</p><h2 id="dynamically-change-terminal-background">Dynamically Change Terminal Background</h2><p>The oh-my-posh Azure segment now does exactly what I want, but wouldn&apos;t it be great to have an even <em>more</em> obvious way to see which cloud I was logged into? And be able to see it all the time rather than only when I&apos;m in the <code>~/az</code> directory? For example, notice in the screenshot below, I&apos;m logged into regular Azure public (&quot;AzureCloud&quot; is showing as my environment in the Az segment) and the normal Azure icon is shown in the bottom right as my terminal background.</p><!--kg-card-begin: markdown--><p><img src="https://stevemichelotti.blob.core.windows.net/images/az-terminal-public.png" alt="Azure Terminal public" loading="lazy"></p>
<!--kg-card-end: markdown--><p>I switch back and forth between Azure and Azure Gov frequently. Scott suggested that it would be cool to dynamically change that icon in the lower right to show that as well. However, integration between oh-my-posh and Windows Terminal isn&apos;t natively supported. But what about a more &quot;brute force&quot; approach? I could create a couple of functions in my PowerShell profile ($profile) that: </p><ol><li>Set the Azure cloud via the <code>az cloud set</code> command (the oh-my-posh Az segment will change accordingly)</li><li>Set the Windows Terminal background image to change depending on cloud</li></ol><p>The Windows Terminal doesn&apos;t have any magical API that you can programmatically manipulate. However, it <strong>does</strong> have a settings.json file that it watches for changes. So I can just change the <code>backgroundImage</code> property of the correct profile and that <em>should</em> do the trick. Here are the functions I added to my $profile:</p><!--kg-card-begin: markdown--><pre><code class="language-powershell">function Set-AzureCloud() {
  param([string]$cloud, [string]$img)

  az cloud set --name $cloud

  # Set background for Windows Terminal
  $settingsPath = &quot;$env:LocalAppData\Packages\Microsoft.WindowsTerminalPreview_*\LocalState\settings.json&quot;
  $json = (Get-Content $settingsPath -Raw) | ConvertFrom-Json -Depth 32
  $psProfile = $json.profiles.list.Where({$_.name -eq &apos;PowerShell&apos;})
  $($psProfile).backgroundImage = &quot;$home\Dropbox\utils\terminal\$img&quot;
  $json | ConvertTo-Json -Depth 32 | Set-Content (Get-Item $settingsPath).FullName
}

function Set-AzPublic {
  Set-AzureCloud &apos;AzureCloud&apos; &apos;azure-tr-236x225.png&apos;
}

function Set-AzGov {
  Set-AzureCloud &apos;AzureUSGovernment&apos; &apos;ages-tr-236x225.png&apos;
}
</code></pre>
<!--kg-card-end: markdown--><p>With that in place, it enables me to have nice PowerShell commands (with auto-completion) on my command line - <code>Set-AzPublic</code> and <code>Set-AzGov</code> - that enable me to do this:</p><!--kg-card-begin: markdown--><p><img src="https://stevemichelotti.blob.core.windows.net/images/ages-terminal.gif" alt="Dynamic Terminal" loading="lazy"></p>
<!--kg-card-end: markdown--><p>(Note: the red-white-blue Azure logo is completely non-official and just something our team uses internally.)</p><p>For those looking to customize their own terminal, I recommend starting with Scott Hanselman&apos;s <a href="https://www.hanselman.com/blog/my-ultimate-powershell-prompt-with-oh-my-posh-and-the-windows-terminal?ref=stevemichelotti.com">Ultimate PowerShell prompt</a>. Additionally, I keep my terminal customizations (including all the code I showed in this post, and more) on <a href="https://github.com/smichelotti/my-terminal?ref=stevemichelotti.com">my GitHub here</a>.</p>]]></content:encoded></item><item><title><![CDATA[New Pluralsight Course - Dapper: Getting Started]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I just released my latest (and 11th!) Pluralsight course: <a href="https://app.pluralsight.com/library/courses/getting-started-dapper/table-of-contents?ref=stevemichelotti.com">Dapper: Getting Started</a>. <a href="https://github.com/StackExchange/Dapper?ref=stevemichelotti.com">Dapper</a> provides a super fast library for mapping between databases and .NET objects. This code-focused course will introduce you to all the basics you need to be productive with Dapper and incorporate it into your own apps. This</p>]]></description><link>https://stevemichelotti.com/new-pluralsight-course-dapper/</link><guid isPermaLink="false">5d06f1f127e3d40037cfd1c2</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Mon, 17 Jun 2019 01:52:07 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I just released my latest (and 11th!) Pluralsight course: <a href="https://app.pluralsight.com/library/courses/getting-started-dapper/table-of-contents?ref=stevemichelotti.com">Dapper: Getting Started</a>. <a href="https://github.com/StackExchange/Dapper?ref=stevemichelotti.com">Dapper</a> provides a super fast library for mapping between databases and .NET objects. This code-focused course will introduce you to all the basics you need to be productive with Dapper and incorporate it into your own apps. This course is largely a &quot;refresh&quot; of my <a href="https://app.pluralsight.com/library/courses/dotnet-micro-orms-introduction/table-of-contents?ref=stevemichelotti.com">origial Micro ORMs course</a> from back in 2013 - but updated for the modern day using Visual Studio 2019. You can check out this course <a href="https://app.pluralsight.com/library/courses/getting-started-dapper/table-of-contents?ref=stevemichelotti.com">here</a>.</p>
<p><img src="http://cdn.stevemichelotti.com/images/dapper-getting-started.png" alt="Dapper: Getting Started" loading="lazy"></p>
<p>Also, a few months ago I released <a href="https://app.pluralsight.com/library/courses/ng-bootstrap-playbook/table-of-contents?ref=stevemichelotti.com">ng-bootstrap Playbook</a>. <a href="https://ng-bootstrap.github.io/?ref=stevemichelotti.com">ng-bootstrap</a> provides seamless integration between the latest versions of Angular and Bootstrap. This course will introduce you to every component in the ng-bootstrap library and show you how to easily use them in your own apps. You can check out this course <a href="https://app.pluralsight.com/library/courses/ng-bootstrap-playbook/table-of-contents?ref=stevemichelotti.com">here</a>.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[New Pluralsight Course: ng-bootstrap Playbook]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I&apos;m pleased to announce my latest (and 10th!) Pluralsight course went live last week: <a href="https://app.pluralsight.com/library/courses/ng-bootstrap-playbook?ref=stevemichelotti.com">ng-bootstrap Playbook</a>.</p>
<p><a href="https://ng-bootstrap.github.io/?ref=stevemichelotti.com">ng-bootstrap</a> provides a native Angular implementation for the rich components in the Bootstrap library, enabling great user experiences. In this course, ng-bootstrap Playbook, you will learn how to fully utilize the ng-bootstrap</p>]]></description><link>https://stevemichelotti.com/new-pluralsight-course-ng-bootstrap/</link><guid isPermaLink="false">5d06ef6be9c13100173aebfe</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Wed, 05 Dec 2018 00:13:42 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I&apos;m pleased to announce my latest (and 10th!) Pluralsight course went live last week: <a href="https://app.pluralsight.com/library/courses/ng-bootstrap-playbook?ref=stevemichelotti.com">ng-bootstrap Playbook</a>.</p>
<p><a href="https://ng-bootstrap.github.io/?ref=stevemichelotti.com">ng-bootstrap</a> provides a native Angular implementation for the rich components in the Bootstrap library, enabling great user experiences. In this course, ng-bootstrap Playbook, you will learn how to fully utilize the ng-bootstrap library. First, you will see how to install ng-bootstrap into your own apps and get up and running quickly. Next, you will get familiar with how to use ng-bootstrap Forms and Structural components. Finally, you will explore ng-bootstrap Informational and Navigation components. When you&apos;re finished with this course, you will have the skills and knowledge of ng-bootstrap needed to fully leverage these awesome components in your apps.</p>
<h4 id="coursemodules">Course Modules</h4>
<ol>
<li><strong>Introduction</strong> - This module introduces the framework and we preview the demo app used in the course.</li>
<li><strong>Initial App Setup</strong> - This modules sets up the initial app structure and installs ng-bootstrap into the app.</li>
<li><strong>Basic Forms</strong> - Here we cover the basic forms components including the datepicker, timepicker, rating, and typeahead.</li>
<li><strong>Structural Components</strong> - This module covers the structural components including the accordion, modal, tabs, and carousel.</li>
<li><strong>Informational Components</strong> - Next we dive into information components such as the alert, tooltip, popover, and progressbar.</li>
<li><strong>Navigation Components</strong> - The final module will deep dive into pagination - both on the client-side and server-side.</li>
</ol>
<p>If you want to learn how to quickly build apps with the latest version of Angular and Bootstrap leveraging the ng-bootstrap library, checkout my latest course on <a href="https://app.pluralsight.com/library/courses/ng-bootstrap-playbook?ref=stevemichelotti.com">ng-bootstrap</a>.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[One Year at Microsoft]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>It&apos;s now been a year since I joined Microsoft and I have to say, it&apos;s been quite a ride. Last year I joined the <a href="https://azure.microsoft.com/en-us/overview/clouds/government/?ref=stevemichelotti.com">Azure Government</a> Engineering team - this is one of the only engineering teams at Microsoft that is not based primarily in Redmond</p>]]></description><link>https://stevemichelotti.com/one-year-at-microsoft/</link><guid isPermaLink="false">5d06ef6be9c13100173aebfd</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Wed, 10 Jan 2018 20:12:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>It&apos;s now been a year since I joined Microsoft and I have to say, it&apos;s been quite a ride. Last year I joined the <a href="https://azure.microsoft.com/en-us/overview/clouds/government/?ref=stevemichelotti.com">Azure Government</a> Engineering team - this is one of the only engineering teams at Microsoft that is not based primarily in Redmond (which makes sense since we&apos;re close to the Federal government in Washington, DC). I generally travel to Redmond about every 8 weeks for face-to-face meetings and other activities - this definitely helps me be &quot;connected to the mothership&quot;.</p>
<p>I was fortunate to join a growing team of passionate people that are totally invested in truly empowering our government agencies by bringing the best Microsoft technologies to their mission. Prior to joining Microsoft, I heard a lot of quotes about &quot;customer obsessed&quot;, but I didn&apos;t know if that was reality or just marketing hype. What I&apos;ve found in the last year on my team is that it&apos;s 100% real. All team activities are tracked back <em>directly</em> to customer demands. Our work is all prioritized directly in response to customers needs.</p>
<p>Similar to other teams like ours at Microsoft, most everyone on the team has some sort of &quot;Program Manager&quot; title. I&apos;ve found that <a href="https://blogs.msdn.microsoft.com/farshid/2007/05/10/what-does-a-microsoft-program-manager-really-do-demystifying-the-pm-role/?ref=stevemichelotti.com">this post</a> from back in 2007 - although being over a decade old - still does a good job of describing the PM role at Microsoft in general.</p>
<p>Because Azure Government isn&apos;t just a single product/service - it encapsulates <em>all</em> of Azure services - I get the opportunity to work with most any Azure Service. Though in the last year I&apos;ve found a lot of my time focused in the areas of AI, Cognitive Services, and Machine Learning.</p>
<p>In my role specifically, I&apos;ve found that about 50% of my time is spent on public customer-facing activities, and about 50% on non-public activities. In my public facing role, I&apos;m focused on developer enablement for Azure Government. This includes several activities including:</p>
<ul>
<li>Organizing <a href="https://enterprise.microsoft.com/en-us/event/azure-government-hackfest-training/?ref=stevemichelotti.com">Azure Gov HackFest events</a> throughout the US</li>
<li>Publishing blog posts on the <a href="https://blogs.msdn.microsoft.com/azuregov/?ref=stevemichelotti.com">Azure Gov blog</a></li>
<li>Managing the <a href="https://docs.microsoft.com/en-us/azure/azure-government/?ref=stevemichelotti.com">Azure Gov documentation</a></li>
<li>Contributing to open source <a href="https://github.com/topics/azure-government?ref=stevemichelotti.com">Azure Gov code samples</a> to the open source ecosystem, such as the <a href="https://github.com/Azure-Samples/gov-intelligent-mission?ref=stevemichelotti.com">Intelligent Mission</a> app</li>
<li>Creating the <a href="https://channel9.msdn.com/blogs/azure-government?ref=stevemichelotti.com">Azure Government Video channel</a> on Channel 9</li>
<li>Delivering numerous presentations on Azure for Government literally all over the world</li>
<li>Ensuring that normal Azure tools work seamlessly with Azure Government</li>
</ul>
<p>Some of the highlights for me was getting the opportunity to give a presentation on <a href="https://www.youtube.com/watch?v=jwgB8PpGd64&amp;ref=stevemichelotti.com">Azure Government at Ignite</a> in Orlando:</p>
<iframe width="560" height="315" src="https://www.youtube.com/embed/jwgB8PpGd64" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe>
<p>I also had the opportunity to travel to the UK and London to deliver presentations to our government customers there. I also went to Australia (Melbourne, Canberra, and Sydney) for similar customer presentations and meetings. This included taking a tour of the new Azure data center in Canberra which was <em>way</em> cooler than I expected.</p>
<p>Another cool experience was doing the demos during one of Jason Zander&apos;s keynotes at the interal Microsoft conference in front of an audience of 2,000 people.</p>
<img src="http://cdn.stevemichelotti.com/images/michelotti-isu-general-resize.png">
<p>Equally as interesting has been my non-public facing activities. This enables me to leverage my development background to build solutions and POCs that are directly relevant for our customers. I informally refer to this as, &quot;does our software do what we say it will do?&quot; If/when we find gaps, we work with the Product teams to drive solutions in our products that will enable our government customers to fulfill mission objectives. Additionally, in this area we work to drive overall Microsoft strategy for Azure Government customers to ensure that we&apos;re producing the tools that our customers are seeking - and that we have referenceable architectures that can be implemented with Azure technology.</p>
<p>In summary, the past year was probably more of a &quot;whirlwind tour&quot; of any year in my career. I can&apos;t wait to see what this year brings.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Hello Microsoft]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>After 8 tremendous year at <a href="https://www.appliedis.com/?ref=stevemichelotti.com">AIS</a>, I have recently decided to move to Microsoft. In my new role at Microsoft, I&apos;m a Program Manager on the <a href="https://azure.microsoft.com/en-us/overview/clouds/government/?ref=stevemichelotti.com">Azure Government</a> Engineering team. My focus will be on developer enablement for the Azure Gov platform. I&apos;ll be working with</p>]]></description><link>https://stevemichelotti.com/hello-microsoft/</link><guid isPermaLink="false">5d06ef6be9c13100173aebfc</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Tue, 10 Jan 2017 16:48:30 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>After 8 tremendous year at <a href="https://www.appliedis.com/?ref=stevemichelotti.com">AIS</a>, I have recently decided to move to Microsoft. In my new role at Microsoft, I&apos;m a Program Manager on the <a href="https://azure.microsoft.com/en-us/overview/clouds/government/?ref=stevemichelotti.com">Azure Government</a> Engineering team. My focus will be on developer enablement for the Azure Gov platform. I&apos;ll be working with developers from Federal, state, and local governments to optimize their use of Azure Government, helping them to build amazing solutions on Azure technology.</p>
<p><a href="https://www.appliedis.com/?ref=stevemichelotti.com">AIS</a> is truly a great company - widely considered by many to be the best Microsoft partner anywhere on the east coast. If you&apos;re a consultant and you want to work with the <strong>best</strong>, AIS is the place you want to be.</p>
<p>In my new role at Microsoft, I&apos;ll still be actively engaged in the developer community through DC/VA/MD/PA and beyond. I&apos;ll still be speaking at local user groups, and I&apos;ll still be authoring courses for <a href="https://app.pluralsight.com/profile/author/steve-michelotti?ref=stevemichelotti.com">Pluralsight</a>.</p>
<p>If you&apos;re a developer (in the government space, in particular), and your organization/agency is in the process of moving to (or considering) Azure Gov, feel free to <a href="https://stevemichelotti.com/contact/">reach out to me</a> anytime - I want to hear from you!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[New Pluralsight Course: Ionic 2]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I&apos;m pleased to announce my latest Pluralsight course has been released: <a href="https://www.pluralsight.com/courses/ionic2-angular2-typescript-mobile-apps?ref=stevemichelotti.com">Building Mobile Apps with Ionic 2, Angular 2, and TypeScript</a>.</p>
<p>The first version of the <a href="http://ionicframework.com/?ref=stevemichelotti.com">Ionic framework</a> took the mobile development world by storm and established itself as the most popular open source framework for building cross-platform</p>]]></description><link>https://stevemichelotti.com/new-pluralsight-course-ionic-2/</link><guid isPermaLink="false">5d06ef6be9c13100173aebfb</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Tue, 01 Nov 2016 13:51:23 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I&apos;m pleased to announce my latest Pluralsight course has been released: <a href="https://www.pluralsight.com/courses/ionic2-angular2-typescript-mobile-apps?ref=stevemichelotti.com">Building Mobile Apps with Ionic 2, Angular 2, and TypeScript</a>.</p>
<p>The first version of the <a href="http://ionicframework.com/?ref=stevemichelotti.com">Ionic framework</a> took the mobile development world by storm and established itself as the most popular open source framework for building cross-platform mobile apps. Built on top of Angular, Ionic enabled developers to write cross-platform mobile apps with the web development tools/frameworks that they were already familiar with. Ionic 2 takes this to a whole new level! Built on top of Angular 2 and TypeScript, Ionic 2 enables developers to take advantage of all the latest advantages of the latest web technologies, as well benefit from all the &quot;lessons learned&quot; in the first version of the Ionic framework.</p>
<p>This is a totally code-focused course. In the beginning of the course, I focus on how you can quickly get started with Ionic 2. After getting started, we build a complete end-to-end app from scratch over the duration of this course which includes navigation, HTTP, numerous Ionic Components, Ionic Native, and more!</p>
<h3 id="coursemodules">Course Modules</h3>
<ol>
<li><strong>Introduction</strong> - This module introduces the Ionic 2 framework. We will cover helpful background context on what Ionic is. We will also preview the app that we will be building throughout this course.</li>
<li><strong>Getting Started with Ionic 2</strong> - This module introduces getting started with Ionic 2 hands on. We&apos;ll cover installation, creating your first project, and running your app with several different mechanisms including deploying directly to a mobile device.</li>
<li><strong>Navigation</strong> - This module introduces Ionic 2 Navigation. We&apos;ll first understand the Ionic Navigation Stack and then see how to use it hands-on to navigate to different screens. Advanced navigaton topics will also be shown.</li>
<li><strong>Working with HTTP and Lifecycle Events</strong> - This module covers working with HTTP and Ionic 2 Lifecycle Events. We&apos;ll show how to retrieve data from an HTTP Web API with Promises and RxJS, while also providing visual indicators to the user.</li>
<li><strong>Ionic 2 Components</strong> - This module covers the most commonly used Ionics 2 components. We&apos;ll cover numerous components including Lists, Buttons, Cards, Grids, DateTime, Toggle, Badges, Alerts, Toasts, and more.</li>
<li><strong>Ionic 2 Components - Beyond the Basics</strong> - This module covers more advanced scenarios for Ionic 2 Components. We&apos;ll show numerous components including Events, Pull to Refresh, and Virtual Scroll for large lists. The module will conclude by implementing mapping and driving directions.</li>
<li><strong>Ionic Native</strong> - This module covers Ionic Native which gives you access to the native features of the device. We&apos;ll show numerous native plugins including the Camera, Barcode scanner, Accelerometer, Vibration, SQLite, and more.</li>
<li><strong>Customizing Ionic 2</strong> - This module covers how to customize Ionic 2. We&apos;ll customize the colors of the default theme, as well as generate custom app icons and splash screen.</li>
</ol>
<p>The following is the official description of the course:</p>
<blockquote>
<p>Ionic has established itself as the most popular open source framework for building cross-platform mobile apps. This code-focused course explores the exciting new Ionic 2 framework, and shows how to build mobile apps using Angular 2 and TypeScript. In this course, we&apos;ll see how to quickly get up and running with Ionic 2. We will then build a complete app from scratch over the duration of the course. The course will cover screen navigation, working with HTTP, numerous Ionic 2 components including advanced scenarios. We will also cover using native device features such as geolocation, the device camera, barcode scanner, accelerometer, and more!</p>
</blockquote>
<p><em>Note:</em> The course was created using the final beta of Ionic 2 and there were some small changes in the RC releases. This <a href="https://github.com/smichelotti/Ionic2Course?ref=stevemichelotti.com">Github repository for the course</a> provides all the updates you&apos;ll need to be up-to-date with the latest Ionic 2 releases.</p>
<p>If you want to learn how to quickly build mobile apps with the latest cross-platform technologies, check out <a href="https://www.pluralsight.com/courses/ionic2-angular2-typescript-mobile-apps?ref=stevemichelotti.com">my latest course</a> on <a href="http://ionicframework.com/docs/v2/?ref=stevemichelotti.com">Ionic 2</a>!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[8 Things New Developers Should Do]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I recently received an email from a new developer asking for some advice:</p>
<blockquote>
<p>I recently came out of school and will start work as an entry level C#/.NET developer in a few weeks. It&apos;ll be my first true work experience. What were your trials and tribulations when</p></blockquote>]]></description><link>https://stevemichelotti.com/8-things-new-developers-should-do/</link><guid isPermaLink="false">5d06ef6be9c13100173aebfa</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Wed, 19 Oct 2016 01:54:48 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I recently received an email from a new developer asking for some advice:</p>
<blockquote>
<p>I recently came out of school and will start work as an entry level C#/.NET developer in a few weeks. It&apos;ll be my first true work experience. What were your trials and tribulations when you first started out? What lessons would you imprint on newbies like me fresh outta school and walking into this vast software development world?</p>
</blockquote>
<p><strong>This is a great question.</strong></p>
<p>First of all, what an amazing time it is to be a software developer! Technology has changed so much since I was starting out and there are so many exciting opportunities available if you grab onto them.</p>
<p>Having said that, the question has made me reflect on what I did early in my career (and still do to this day). The following is my 2 cents and it is <strong>completely subjective</strong> to my own experiences. Here are the 8 things I think every developer should do when starting out.</p>
<h2 id="1pickyourmentorswisely">1. Pick your mentors wisely</h2>
<p>I feel strongly that one of the best things I did early in my career was that I focused on finding mentors. In fact, I think picking your mentors is so important, it&apos;s not a coincidence that I&apos;m putting this as #1. Understand that not everyone is willing to be a mentor to you, or maybe they don&apos;t have time. When I found a mentor in my own company I made sure that I learned as much as I could from them - anything that they were willing to teach me, I was willing to learn. They had way more experience than me - both technical and non-technical - and I was more interested in learning what they knew than trying to prove what I knew - after all, it was early in my career so I didn&apos;t know much. Spend more time <em>listening</em> than <em>talking</em> - and ask thoughtful questions.</p>
<p>My mentors did not always work at the same company as me. In fact, I had many mentors that I never met and, in fact, they had no idea they were my mentors! I would subscribe to blogs. I would always make sure to go watch certain speakers&apos; presentations. Again, once I identified a mentor, I tried to absorb everything I possibly could from that person.</p>
<h2 id="2focusoncommunicationskillsespeciallyverbal">2. Focus on communication skills - especially verbal</h2>
<p>Yes, it&apos;s important learn as much technology as you possibly can and the more deep technical knowledge you have, the better. However, if you truly want to maximize your success in the software development profession, <strong>focus on improving your communication skills - especially verbal</strong>. This can take many different forms.</p>
<ul>
<li>One-on-one with another developer - When you&apos;re having a conversation with another developer, make sure you&apos;re clearly articulating your questions or idea. If another developer is asking you a question, are you sure you&apos;ve understood the question? Can you explain the answer in a way that developer understands?</li>
<li>One-on-one with a non-developer - Great, you can interact with other developers - but what if your non-technical Project Manager comes to you with a question? You can&apos;t just throw a barrage of technical jargon at the PM and expect them to understand. I can&apos;t tell you how many times in my career, a PM or manager has come to me to ask me to explain something to them that another developer confused them on.</li>
<li>Group setting - can you clearly and succinctly articulate your thoughts in a meeting? Every meeting is an opportunity for practice.</li>
<li>Public Speaking - Not everyone is going to become a world renowned public speaker like <a href="http://www.hanselman.com/?ref=stevemichelotti.com">Scott Hanselman</a>, but I challenge you to reach outside your comfort zone. Start small. Give a short presentation to a handful of developers at your company about something new you learned. Once you&apos;re comfortable, try your hand at presenting at a local user group. I&apos;ve given <a href="https://stevemichelotti.com/speaking/">a lot of presentations</a> in the last few years, and I still look at each presentation as a way to improve in some aspect of my public speaking. It may or may not be in the cards for you to do this regularly, but it will benefit your career when you&apos;re in meetings and presenting your ideas to your customers.</li>
<li>Written - I&apos;ve been emphasizing verbal communication skills here because I do feel this takes priority. But don&apos;t forget about your written communication skills too. Can you write emails clearly, yet succinctly? Can you author a design document that is easy to understand? These are areas that will come up repeatedly in your career.</li>
</ul>
<h2 id="3learnthebusinessdomain">3. Learn the business domain</h2>
<p>Too often, new developers just focus on learning all the features of a language or framework. While this is important, it is just as important to become knowledgeable on your current business domain. In my first technology job, I worked for a company that built credit lending software for banks. I became an expert in consumer lending and it helped me thrive at that company in so many ways. You&apos;ll understand your software better. You&apos;ll be able to communicate with managers and customers better. Learn your business domain.</p>
<h2 id="4adoptalearningmindset">4. Adopt a learning mindset</h2>
<p>So you&apos;ve just spent the last couple of years learning in school and you&apos;re now ready to put what you&apos;ve learned into practice starting your career - this is exciting! However, what you&apos;ll soon discover is that your learning process has barely started. Technology...changes...FAST. Much of what you know now will be obsolete in a few years. It can be exhausting to keep up on all the technologies. Here&apos;s a secret - it&apos;s <strong>impossible</strong> to keep up on all the new technologies. You have to accept that fact now. For those that grasp the concept of being a &quot;life-long learner&quot; and embrace it, you&apos;ll have much success to look forward to. However, if you&apos;re looking for a profession where you&apos;re not required to constantly learn new things, then software development is going to be frustrating for you.</p>
<h2 id="5neverbeafraidtoaskquestions">5. Never be afraid to ask questions</h2>
<p>Too often people (especially developers) refrain from asking questions because they&apos;re afraid that their questions will make them look dumb. One thing that I did well early on in my career is that I wasn&apos;t afraid of asking questions. I still do this. Believe me, it&apos;s <em>way</em> better to ask a couple extra questions up front, than to get to the end of a task and people realize you didn&apos;t know what you were doing!</p>
<h2 id="6figureoutwhatyourepassionateabout">6. Figure out what you&apos;re passionate about</h2>
<p>We just established that it&apos;s impossible to stay up-to-date on all the new technologies. Do your best to figure out which technologies really capture your interest. Do you like front end work? Do you like back end? Perhaps developing mobile apps really gets you excited. You may not always have the opportunity to work in your #1 technology of choice, but make sure you identify what really gets you excited. If you&apos;re going to deliver a presentation, make sure you really love the technology you&apos;re presenting about.</p>
<h2 id="7gotheextramile">7. Go the extra mile</h2>
<p>Early in my career, I wasn&apos;t shy about going the extra mile with side projects at home. It wasn&apos;t even that difficult because it was before I had kids and before my free time was quickly filled with family activities. At my first company, I developed an app on the side (on my own time) just because it would make my current job easier, and it provided me an opportunity to learn a new programming language. One day a manager saw me using the app and asked me what it was. One thing led to another and within a couple of months, my little utility app was transitioned to replace the existing UI of one of our products, and I was in my first lead-developer role. You just never know what can happen. Even if my app hadn&apos;t caught the attention of the company, it was an extremely valuable learning experience for me to build an app on my own.</p>
<p>Go the extra mile. Read books. Watch <a href="https://www.pluralsight.com/?ref=stevemichelotti.com">Pluralsight</a> courses. Go to watch user group presentations. Contribute to an open source project. Spend a little time outside of work honing your craft.</p>
<h2 id="8neverbecondescending">8. Never be condescending</h2>
<p>This might seem like basic advice for a developer starting out since new developers naturally won&apos;t have as much technical knowledge as other developers with several years experience - but it&apos;s not. I&apos;ve been amazed at some interactions I&apos;ve had with junior developers where they came across as condescending or cocky - probably trying to &quot;trick&quot; people into thinking they know more than they do - this doesn&apos;t work. Regardless of whether you have one year of experience or 10 years of experience - <strong>never be condescending</strong>. Absolutely nothing positive will come from it.</p>
<p>I have never met anyone with as much knowledge on Microsoft Azure anywhere in the world as <a href="https://twitter.com/vlele?ref=stevemichelotti.com">Vishwas Lele</a>, my colleague at <a href="https://www.appliedis.com/?ref=stevemichelotti.com">AIS</a>. And yet, I have yet to meet anyone in my entire career as <em>humble</em> as he is - <strong>this</strong> is the example of what you should emulate professionally.</p>
<h2 id="bonustechnologyspecific">Bonus - Technology Specific</h2>
<p>OK, I know I said there were 8 things but I&apos;m going to throw in one &quot;bonus&quot; item. Up until now, really nothing I&apos;ve talked about has been technology specific. And I believe these 8 things stand the test of time, regardless of technology. But I will offer a couple of technology-specific items with the caveat that this is relevant in 2016.</p>
<ul>
<li>Learn a Cloud platform - If you&apos;re a Microsoft developer, then it makes sense for this cloud platform to be Azure. If you&apos;re not a Microsoft developer, then perhaps it&apos;s AWS. But regardless, start getting familiar with at least one of the major cloud providers (if not multiple).</li>
<li>Learn JavaScript/Node - If you&apos;re a web developer, I strongly believe you should learn not only JavaScript but also Node.js. Regardless of your server technology of choice (ASP.NET, Java, Ruby, etc.), JavaScript and Node are just too important. JavaScript is everywhere - front end code (Angular, React, etc.), cross-platform mobile apps, server-side Node. And even if you&apos;re not writing server-side Node code, the major web development and build tools such as Gulp, Grunt, Webpack, etc. are Node-based tools. Learn them - it will help you.</li>
</ul>
<h2 id="conclusion">Conclusion</h2>
<p>So there you have it - my own opinion on what new developers should know starting out. Now here&apos;s the irony: these are principals that I believe still hold true for me even at this stage of my career. I believe software development is one of the most rewarding careers you can have. Accept the challenge - embrace it - and don&apos;t look back.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Integrate Angular 2 Google Maps into Ionic 2]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><strong>UPDATE 11/12/2016: The following post is in reference to Ionic RC1. However, in RC2 they removed the rollup dependency and moved back to webpack - hence, a custom &quot;config&quot; section for rollup is no longer required.</strong></p>
<p><a href="https://angular-maps.com/?ref=stevemichelotti.com">Angular2 Google Maps</a> (AGM) is a great component for integrating</p>]]></description><link>https://stevemichelotti.com/integrate-angular-2-google-maps-into-ionic-2/</link><guid isPermaLink="false">5d06ef6be9c13100173aebf9</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Mon, 10 Oct 2016 14:53:35 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><strong>UPDATE 11/12/2016: The following post is in reference to Ionic RC1. However, in RC2 they removed the rollup dependency and moved back to webpack - hence, a custom &quot;config&quot; section for rollup is no longer required.</strong></p>
<p><a href="https://angular-maps.com/?ref=stevemichelotti.com">Angular2 Google Maps</a> (AGM) is a great component for integrating Google Maps into Angular 2 apps. There were several ways you could do this with Angular 1.x apps, but <a href="https://angular-maps.com/?ref=stevemichelotti.com">Angular2 Google Maps</a> is the best way I&apos;ve seen of doing with with Angular 2 apps. There is minimal code required and it is super easy to get started, in large part due to solid documentation on its <a href="https://angular-maps.com/docs/getting-started.html?ref=stevemichelotti.com">Getting Started page</a>.</p>
<p>I&apos;ve previously incorporated this into regular Angular 2 web apps running in a browser, as well as <a href="http://ionicframework.com/docs/v2/?ref=stevemichelotti.com">Ionic 2</a> mobile apps. However, in the course of recording my latest <a href="http://app.pluralsight.com/author/steve-michelotti?ref=stevemichelotti.com">Pluralsight course</a>, Ionic 2 (which had been in the final beta) dropped the <a href="http://blog.ionic.io/announcing-the-ionic-2-release-candidate/?ref=stevemichelotti.com">Ionic 2 Release Candidate</a>. This was a significant release as Ionic 2 was updated to take a dependency on Angular 2 final. When this happened, not only did the previous implementation with AGM break, but even following the instructions on the <a href="https://angular-maps.com/docs/getting-started.html?ref=stevemichelotti.com">AGM Getting Started page</a> don&apos;t exactly work for an Ionic 2 app. This blog post will document how you can get up and running quickly with AGM in an Ionic 2 app.</p>
<p>First thing&apos;s first, let&apos;s generate our initial Ionic 2 app. If you haven&apos;t already, make sure the Ionic CLI is installed:</p>
<pre><code class="language-shell">npm install -g ionic
</code></pre>
<p>Make sure you&apos;re on version 2:</p>
<pre><code class="language-shell">ionic -v
2.1.0
</code></pre>
<p>Let&apos;s create our Ionic 2 project in the usual way:</p>
<pre><code class="language-shell">ionic start ionic2-google-maps-test blank --ts --v2
</code></pre>
<p>Now let&apos;s follow the instructions on the AGM Getting Started page by installing AGM into our project:</p>
<pre><code class="language-shell">npm install angular2-google-maps --save
</code></pre>
<p>The Ionic 2 RC now uses the <a href="https://angular.io/docs/ts/latest/guide/ngmodule.html?ref=stevemichelotti.com">NgModule</a> approach, which allows you to declare your dependencies up front.</p>
<p>Per the AGM guide, we import <code>AgmCoreModule</code> into app.module.ts and add it to our imports list shown on line numbers 6 and 15:</p>
<pre class="brush: js; highlight: [6, 15]">
import { NgModule } from &apos;@angular/core&apos;;
import { IonicApp, IonicModule } from &apos;ionic-angular&apos;;
import { MyApp } from &apos;./app.component&apos;;
import { HomePage } from &apos;../pages/pages&apos;;

import { AgmCoreModule } from &apos;angular2-google-maps/core&apos;;

@NgModule({
  declarations: [
    MyApp,
    HomePage
  ],
  imports: [
    IonicModule.forRoot(MyApp),
    AgmCoreModule.forRoot({ apiKey: &apos;{your-api-key-here}&apos;})
  ],
  bootstrap: [IonicApp],
  entryComponents: [
    MyApp,
    HomePage,
  ],
  providers: []
})
export class AppModule {}
</pre>
<p>And of course we&apos;ll also put the appropriate mark-up on our desired page per the Getting Started instructions:</p>
<pre class="brush: html">
&lt;sebm-google-map [latitude]=&quot;lat&quot; [longitude]=&quot;lng&quot;&gt;
  &lt;sebm-google-map-marker [latitude]=&quot;lat&quot; [longitude]=&quot;lng&quot;&gt;&lt;/sebm-google-map-marker&gt;
&lt;/sebm-google-map&gt;
</pre>
<p>Let&apos;s run our Ionic app:</p>
<pre><code class="language-shell">ionic serve
</code></pre>
<p>However, when we do this, we get the following error:</p>
<pre><code class="language-shell">[14:36:28]  bundle dev started ...
[14:36:34]  bundle dev failed:  Module c:\dev\ionic2-google-maps-test\node_modules\angular2-google-maps\core\index.js does not export AgmCoreModule (imported by c:\dev\ionic2-google-maps-test\.tmp\app\app.module.js)
[14:36:34]  bundle dev failed:  Module c:\dev\ionic2-google-maps-test\node_modules\angular2-google-maps\core\index.js does not export AgmCoreModule (imported by c:\dev\ionic2-google-maps-test\.tmp\app\app.module.js)
[14:36:34]  Error: Module c:\dev\ionic2-google-maps-test\node_modules\angular2-google-maps\core\index.js does not export AgmCoreModule (imported by c:\dev\ionic2-google-maps-test\.tmp\app\app.module.js)
</code></pre>
<p><strong>&quot;\angular2-google-maps\core\index.js does not export AgmCoreModule&quot;</strong>? We followed the instructions perfectly so why is this happening? Our intellisense at design time seemed to have no problem with it - why is Ionic having a problem when it tries to actually run?</p>
<p>It turns out, the answer can be found in the <strong>Bundle</strong> section in the Ionic <a href="http://ionicframework.com/docs/v2/resources/app-scripts/?ref=stevemichelotti.com">App Build Scripts</a> documentation page. For the RC release, Ionic 2 moved from a gulp-based build process to one that uses <a href="http://rollupjs.org/?ref=stevemichelotti.com">rollup.js</a> for bundling. Most of the time third-party libraries &quot;just work&quot;, but in some cases, additional information needs to be provided to Rollup so that it knows what is being exported. This is the problem happening with AGM.</p>
<p>The get around this, we need to create our own <code>rollup.config.js</code> file in our project. The best way to do that is to find the existing <code>rollup.config.js</code> file in the <code>node_modules/@ionic/app-scripts/config</code> directory local to your project - copy that file - then create a directory called <code>scripts</code> right in the root of your project and paste that file there. In your file, find the <code>plugins()</code> section and add a <code>namedExports</code> property to <code>commonjs()</code> as shown here:</p>
<pre class="brush:js; highlight:[4,5,6]">
plugins: [
    builtins(),
    commonjs({
      namedExports: {
        &apos;node_modules/angular2-google-maps/core/index.js&apos;: [&apos;AgmCoreModule&apos;]
      }
    }),
    nodeResolve({
      module: true,
      jsnext: true,
      main: true,
      browser: true,
      extensions: [&apos;.js&apos;]
    }),
    globals(),
    json()
  ]
</pre>
<p>This tells Rollup that yes, angular2-google-maps does in fact export <code>AgmCoreModule</code>. We now need Ionic to know about our custom <code>rollup.config.js</code> file so let&apos;s open <code>package.json</code> in our project root. Add a <code>config</code> section that points to your custom file:</p>
<pre class="brush: js">
&quot;config&quot;: {
    &quot;ionic_rollup&quot;: &quot;./scripts/rollup.config.js&quot;
  },
</pre>
<p>Now when you run the <code>ionic serve</code> command, everything should work just fine!</p>
<p>Here is a <a href="https://github.com/smichelotti/ionic2-google-maps-test?ref=stevemichelotti.com">Github repo with the complete working code</a>. My (upcoming) Ionic 2 course on Pluralsight was created with the final beta so a different approach is shown in that video. But for Ionic 2 RC and beyond, this should enable everyone to easily integrate AGM with Ionic 2.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[TechBash 2016]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>Last week I had the pleasure of presenting at the <a href="http://www.techbash.com/?ref=stevemichelotti.com">TechBash 2016</a> conference. This was the first year of TechBash, but it was such a success, TechBash 2017 has already been announced.</p>
<p>If you&apos;re looking for a great, high-quality conference on the east coast, I strongly recommend TechBash</p>]]></description><link>https://stevemichelotti.com/techbash-2016/</link><guid isPermaLink="false">5d06ef6be9c13100173aebf8</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Mon, 03 Oct 2016 23:38:29 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>Last week I had the pleasure of presenting at the <a href="http://www.techbash.com/?ref=stevemichelotti.com">TechBash 2016</a> conference. This was the first year of TechBash, but it was such a success, TechBash 2017 has already been announced.</p>
<p>If you&apos;re looking for a great, high-quality conference on the east coast, I strongly recommend TechBash 2017. TechBash 2016 had a ton of high quality speakers, including keynotes from <a href="https://twitter.com/Pete_Brown?ref=stevemichelotti.com">Pete Brown</a> and <a href="https://medium.com/@gblock/?ref=stevemichelotti.com">Glenn Block</a>. In my opinion, the TechBash organizers did a great job selecting presentation topics that covered a wide range of technology areas. You can check out the <a href="http://www.techbash.com/sessions?ref=stevemichelotti.com">sessions here</a>.</p>
<p>The venue - <a href="https://www.kalahariresorts.com/pennsylvania?ref=stevemichelotti.com">Kalahari Resort</a> in the Pocono Mountains - was absolutely beautiful. Its location on the east coast makes it an easy drive, even for someone like me coming from the Baltimore/DC area. One aspect I <em>really</em> liked about this conference was the attendee lounge - a place where attendees and speakers could easily network. So often at conferences there is a private &quot;speakers lounge&quot; that is hidden away from attendees which can have an &quot;elitist&quot; feel. At TechBash the speakers are totally approachable and I enjoyed spending time in the attendee lounge having conversations with attendees, conference organizers, and other speakers. Additionally, evening events were planned where once again, attendees and speakers could come together for more networking, etc. The conference organizers were constantly soliciting feedback from attendees - always looking for ways to make the conference even better.</p>
<p>During the week, I presented three separate talks:</p>
<ul>
<li><a href="http://www.techbash.com/sessions/azure-web-apps?ref=stevemichelotti.com">Azure Web Apps</a></li>
<li><a href="http://www.techbash.com/sessions/c--new-language-features?ref=stevemichelotti.com">C# 6 New Language Features</a></li>
<li><a href="http://www.techbash.com/sessions/ionic--building-mobile-apps-with-the-ionic-framework-and-angularjs?ref=stevemichelotti.com">Ionic 2: Building Mobile Apps With the Ionic Framework and AngularJS</a></li>
</ul>
<p>In another nice touch, you can download the slides and code samples for my presentations, and <em>all</em> conference presentations at this central <a href="https://github.com/TECHbash/TechBash2016?ref=stevemichelotti.com">TechBash GitHub repository</a>.</p>
<p>If you&apos;re looking for a great conference that has a &quot;big conference&quot; feel but is still small enough to allow for direct networking with attendees and speakers, then you should definitely put TechBash 2017 on your calendar for next year. Personally, I can&apos;t wait to go back.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[New Pluralsight Course: Yeoman Fundamentals]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I&apos;m pleased to announce my latest Pluralsight course has been released: <a href="https://www.pluralsight.com/courses/yeoman-fundamentals?ref=stevemichelotti.com">Yeoman Fundamentals</a>.</p>
<p>With so many code generation and scaffolding frameworks available today, it&apos;s not always easy to distinguish which tools to use. With the widespread adoption of Node and JavaScript, <a href="http://yeoman.io/?ref=stevemichelotti.com">Yeoman</a> has vaulted to the</p>]]></description><link>https://stevemichelotti.com/new-pluralsight-course-yeoman-fundamentals/</link><guid isPermaLink="false">5d06ef6be9c13100173aebf6</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Mon, 04 Jan 2016 14:50:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I&apos;m pleased to announce my latest Pluralsight course has been released: <a href="https://www.pluralsight.com/courses/yeoman-fundamentals?ref=stevemichelotti.com">Yeoman Fundamentals</a>.</p>
<p>With so many code generation and scaffolding frameworks available today, it&apos;s not always easy to distinguish which tools to use. With the widespread adoption of Node and JavaScript, <a href="http://yeoman.io/?ref=stevemichelotti.com">Yeoman</a> has vaulted to the top as the &quot;best of breed&quot; tool for scaffolding and code generation - regardless of your technology platform.</p>
<p>This is a totally code-focused course. In the beginning of the course, I focus on getting started with Yeoman - this includes installation and using basic Yeoman generators. After getting started, the primary focus on the course is building your own custom Yeoman generator. Throughout this course, starting from scratch, I build a custom Yeoman generator from start to finish.</p>
<h3 id="coursemodules">Course Modules</h3>
<ol>
<li><strong>Introduction</strong> - This module introduces Yeoman and gives the course overview. It also shows a demo of the Yeoman generator that we will be building throughout the course.</li>
<li><strong>Using Yeoman Generators</strong> - This module introduces using Yeoman generators. It includes getting started installing Yeoman and Yeoman generators. We&apos;ll explore using generators and sub-generators.</li>
<li><strong>Creating a Yeoman Generator</strong> - This module will introduce the basics of creating a custom Yeoman generator. We will set up the environment, understand base classes, as well as explore the Yeoman Runing Context.</li>
<li><strong>Working with the File System</strong> - This module will introduce the Yeoman file system including copying static files and directories, as well as working with Yeoman templates.</li>
<li><strong>User Interactions</strong> - This module will introduce User Interactions with Yeoman. It will include using Yeoman Arguments, Options, and Prompts.</li>
<li><strong>Configuration and Dependencies</strong> - This module will explore managing Yeoman Configuration and dependencies. It will include automatic installation of npm and bower dependencies. Generator Composition will also be shown.</li>
<li><strong>Building a Sub-generator</strong> - This module will introduce how to build a Yeoman Sub-Generator. It will include setting up the folder structure and getting basic functionality working quickly. It will also show options for customizing the sub-generator.</li>
<li><strong>Testing Generators</strong> - This module will demonstrate how to test Yeoman Generators. It will show how to set up the test structure as well as show how to test file creation, file contents, and conditional options.</li>
</ol>
<p>The following is the official description of the course:</p>
<blockquote>
<p>Yeoman has established itself as the preeminent code generation framework for web developers. Yeoman provides a code generator ecosystem that enables best practices and unparalleled productivity. In this course, we&apos;ll see how to quickly get up and running with Yeoman. We will then focus on building our own custom Yeoman generator. This will include working with the Yeoman file system, user interactions, creating sub-generators, testing, and more. By the end of this course, you&apos;ll be able to start building your own custom Yeoman generators!</p>
</blockquote>
<p>If you want to take your developer efficiency to the next level, check out <a href="https://www.pluralsight.com/courses/yeoman-fundamentals?ref=stevemichelotti.com">my latest course</a> on <a href="http://yeoman.io/?ref=stevemichelotti.com">Yeoman</a>!</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Writing a Trello Bookmarklet with Async]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I love <a href="https://trello.com/?ref=stevemichelotti.com">Trello</a> and it seems like I use it for everything. Whether it&apos;s a project for work, a side-project on my own, a personal To Do list, or planning a family vacation - I probably have a Trello board for it.</p>
<p>Although the built-in Search for Trello</p>]]></description><link>https://stevemichelotti.com/writing-a-trello-bookmarklet-with-async/</link><guid isPermaLink="false">5d06ef6be9c13100173aebf5</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Sun, 19 Jul 2015 15:34:23 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I love <a href="https://trello.com/?ref=stevemichelotti.com">Trello</a> and it seems like I use it for everything. Whether it&apos;s a project for work, a side-project on my own, a personal To Do list, or planning a family vacation - I probably have a Trello board for it.</p>
<p>Although the built-in Search for Trello is pretty solid, sometimes it just doesn&apos;t give me what I want. For example, since I have so many different boards, I often want to be able to see all of the cards that are in my &quot;Doing&quot; lists across all boards. To accomplish this, I decided to try to write a Trello <a href="https://en.wikipedia.org/wiki/Bookmarklet?ref=stevemichelotti.com">bookmarklet</a> in conjunction with the <a href="https://trello.com/docs/index.html?ref=stevemichelotti.com">Trello client.js library</a>.</p>
<p>I found the best place to start was the <a href="https://github.com/danlec/Trello-Bookmarklet?ref=stevemichelotti.com">Trello-Bookmarklet repository</a>. This bookmarklet creates Trello cards from other services (e.g., Github, Gmail, etc.) which is functionality I wasn&apos;t necessarily interested in. But what it did show me was a good example of the boilerplate code I needed to include to get started with interacting with the Trello API. This boilerplate code includes:</p>
<ol>
<li>Loading jQuery (needed for DOM manipulation for showing cards)</li>
<li>Loading the Trello client.js library</li>
<li>Authorizing Trello (this includes getting your token from <a href="https://trello.com/app-key?ref=stevemichelotti.com">https://trello.com/app-key</a>, showing a dialog to paste it in, and storing it in local storage)</li>
</ol>
<p>This boilerplate code isn&apos;t trivial and I didn&apos;t want to have to include it every time I wanted to write a bookmarklet. So I refactored this code a little to put it in a file I called <a href="https://github.com/smichelotti/trello-bookmarklets/blob/master/trello-bookmarklet.core.js?ref=stevemichelotti.com">trello-bookmarklet.core.js</a> - I also had it load <a href="https://github.com/caolan/async?ref=stevemichelotti.com">async.js</a> because this library drastically simplifies writing async JavaScript.</p>
<p>For my bookmarklet, I need to use the Trello client.js to execute the following steps:</p>
<ol>
<li>Get the member ID of the current user</li>
<li>Get all the open boards for the current user</li>
<li>For each open board, find all the lists that have &quot;Doing&quot; in the name</li>
<li>For each of these &quot;Doing&quot; lists, get all the cards that are either unassigned or assigned to the current user</li>
<li>Display these cards on a dialog</li>
</ol>
<p>The Trello library doesn&apos;t natively support promises. This is where an async library comes in handy. Without it, I&apos;m find myself in the <a href="https://en.wikipedia.org/wiki/Pyramid_of_doom_(programming)?ref=stevemichelotti.com">Pyramid of Doom</a> with deeply nested callbacks.</p>
<p>My first step is to put the 5 steps above into the async waterfall structure:</p>
<pre class="brush: js;">
async.waterfall([
    // Get ID for current user
    function (callback) {
        callback();
    },
    // Get all open boards
    function (callback) {
        callback(null, boards);
    },
    // Get &quot;Doing&quot; Lists from all open boards
    function (openBoards, callback) {
        callback(null, doingLists);
    },
    // Get all cards across all &quot;Doing&quot; lists
    function (doingLists, callback) {
        callback(null, doingCards);
    }, 
    // Display all &quot;Doing&quot; cards
    function (err, doingCards) {
    }
]);
</pre>
<p>The <a href="https://github.com/caolan/async?ref=stevemichelotti.com#waterfall">waterfall()</a> method will sequentially execute these async functions in order, with each function passing its results to the next function in the sequence. The first argument is an error condition - if you&apos;re not passing anything to the next function, no arguments are necessary (null error condition assumed) - just execute the callback() method to signify function completion. If you are passing objects to the next method, then the first argument is null (no error) and the next arguments will be passed in to the next function.</p>
<p>In the first function, I just want to get my memberId and store it for later:</p>
<pre class="brush:js">
function (callback) {
    Trello.get(&apos;members/me&apos;, { fields: &apos;id&apos; }, function (data) {
        memberId = data.id;
        callback(null);
    });
}
</pre>
<p>The Trello object is available in my context since &quot;core&quot; has loaded it. It enables me to pass a <code>fields</code> parameter so I constrain the response payload to include only the single field (&quot;id&quot;) that I&apos;m interested in.</p>
<p>In the second function, I want to get all my open boards and pass them to the next method:</p>
<pre class="brush:js">
Trello.get(&apos;members/me/boards&apos;, { filter: &apos;open&apos; }, function (boards) {
    callback(null, boards);
});
</pre>
<p>The third function is where things get more interesting. For each open board, I need to find any list that has &quot;Doing&quot; in the name. This means I need to fire off an unknown number of async calls, yet keep their results coordinated - in fact, <strong>combine</strong> their results into a single, larger result. The <a href="https://github.com/caolan/async?ref=stevemichelotti.com#concat">concat()</a> method is exactly what I need here. It will make all these async calls in parallel (I don&apos;t care about the order) and for each call I can store the results. The concat() method then has a final callback which has an array containing <strong>all</strong> of the previously stored results (i.e., all arrays are concatenated together into this larger single array).</p>
<pre class="brush:js">
async.concat(openBoards, function (board, callback) {
    Trello.get(&apos;boards/&apos; + board.shortLink + &apos;/lists&apos;, { filter: &apos;open&apos; }, function (lists) {
        var doing = $.grep(lists, function (item) {
            return item.name.indexOf(&apos;Doing&apos;) !== -1;
        });
        var doingLists = doing.map(function (item) {
            return {
                name: item.name,
                board: board,
                id: item.id
            };
        });
        callback(null, doingLists);
    });
}, function (err, doingLists) {
    callback(null, doingLists);
});
</pre>
<p>The fourth function to get all the cards across these lists uses the same technique with the concat() method (code omitted here for brevity).</p>
<p>The fifth and final function, takes all these cards and displays the result:</p>
<pre class="brush:js">
function (err, doingCards) {
    var htmlResult = &apos;&apos;;
    $.each(doingCards, function (index, card) {
        htmlResult +=
        &apos;&lt;h2&gt;&lt;a target=&quot;_blank&quot; href=&quot;&apos; + card.shortUrl + &apos;&quot;&gt;&apos; + card.name + &apos;&lt;/a&gt;&lt;/h2&gt;&apos; +
        &apos;&lt;p&gt;in &lt;strong&gt;&apos; + card.list + &apos;&lt;/strong&gt; on &lt;strong&gt;&apos; + card.board + &apos;&lt;/strong&gt;&lt;/p&gt;&lt;hr/&gt;&apos;;
    });
    trelloBookmarkletCore.overlayPrompt(htmlResult, false);
});
</pre>
<p>Note the trelloBookmarketCore provides this <code>overlayPrompt()</code> method for convenience.</p>
<p>The final result will look something like this:</p>
<p><img src="http://cdn.stevemichelotti.com/images/trello-bookmarklet.png" alt loading="lazy"></p>
<p>The full code for the trello-doing-cards-bookmarklet.js <a href="https://github.com/smichelotti/trello-bookmarklets/blob/master/trello-doing-cards-bookmarklet.js?ref=stevemichelotti.com">is here</a>. The entire Github repository <a href="https://github.com/smichelotti/trello-bookmarklets?ref=stevemichelotti.com">is located here</a>.</p>
<p>To invoke the bookmarklet, the following code is necessary:</p>
<pre><code>javascript:(function (a) { var b = a.createElement(&quot;script&quot;); b.src = &quot;https://rawgit.com/smichelotti/trello-bookmarklets/master/trello-doing-cards-bookmarklet.js&quot;; a.getElementsByTagName(&quot;head&quot;)[0].appendChild(b);})(document);
</code></pre>
<p>Notice I&apos;m serving the files from rawgit.com but I could certainly move them to my own CDN.</p>
<p>The main optimization that I could make is to use gulp/grunt to concatenate/uglify the JavaScript dependencies (i.e., async, Trello client.js, jQuery) in advance. Currently, there is certainly a little lag the first time it runs to get these files.</p>
<p>Hopefully this is helpful for anyone interested in writing a bookmarklet or interested in using the Trello API in general.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Moving Blog to Ghost and Azure]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>In an effort to <a href="http://www.hanselman.com/blog/BlogInteresting32WaysToKeepYourBlogFromSucking.aspx?ref=stevemichelotti.com">make my blog suck less</a>, I figured it was time to get onto a modern blogging platform. I&apos;ve been blogging for over 10 years and was getting frustrated at the lack of control I had over my current blog engine. Add the fact that</p>]]></description><link>https://stevemichelotti.com/moving-blog/</link><guid isPermaLink="false">5d06ef6be9c13100173aebf4</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Mon, 13 Jul 2015 03:04:57 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>In an effort to <a href="http://www.hanselman.com/blog/BlogInteresting32WaysToKeepYourBlogFromSucking.aspx?ref=stevemichelotti.com">make my blog suck less</a>, I figured it was time to get onto a modern blogging platform. I&apos;ve been blogging for over 10 years and was getting frustrated at the lack of control I had over my current blog engine. Add the fact that Google is now <a href="http://googlewebmastercentral.blogspot.com/2014/11/helping-users-find-mobile-friendly-pages.html?ref=stevemichelotti.com">giving priority to mobile-friendly sites</a>, and it was clear it was time for a change - since I wasn&apos;t able to control the lack of mobile support in my blog, among other things.</p>
<h2 id="whichblogengine">Which Blog Engine?</h2>
<p>There are so many good blogging engines out there now - which one to choose? I really love <a href="http://daringfireball.net/projects/markdown/syntax?ref=stevemichelotti.com">Markdown</a> so I started looking at blogs that supported Markdown. The two blog engines that kept popping up with markdown support were <a href="http://jekyllrb.com/?ref=stevemichelotti.com">Jekyll</a> and <a href="https://github.com/TryGhost?ref=stevemichelotti.com">Ghost</a>. Jekyll can integrate with Github and Github markdown which is interesting. However, I really love Node and Ghost is written in Node which put that to the top of my list - if I wanted to make customization, it would be easiest for me with a Node code base. It&apos;s actively being developed with a great developer community which sparked my interest.</p>
<h2 id="hosting">Hosting</h2>
<p>There are several good hosting options for Ghost blogs but I really wanted to control everything myself with Azure. Azure is an <strong>awesome</strong> option for hosting Node applications. A couple months ago, Scott Hanselman blogged about <a href="http://www.hanselman.com/blog/UPDATEDFor2015HowToInstallTheNodejsGhostBlogSoftwareOnAzureWebAppsAndTheDeployToAzureButton.aspx?ref=stevemichelotti.com">installing Ghost to Azure with the &quot;Deploy to Azure&quot; button</a>. This option specifically uses the <a href="https://github.com/AzureWebApps/Ghost-Azure?ref=stevemichelotti.com">Ghost-Azure Github repository</a>.</p>
<p>There are two main benefits to the Ghost-Azure repository. First, it sets up everything for Azure deployment through the azuredeploy.json file and the &quot;Deploy to Azure&quot; button. Second, it sets up Ghost for an IIS deployment in general - these are things like the web.config file and iisnode.yml. Using this directly is a great option if you just want to get Ghost up and running on Azure quickly for test purposes. But this doesn&apos;t <em>quite</em> fit my needs because I wanted to be able to make any customization to the code should the need arise. So my first step was to fork this repository into <a href="https://github.com/smichelotti/Ghost-Azure?ref=stevemichelotti.com">my own Ghost-Azure Github repository</a>.</p>
<p>Once this was complete, I just did a normal setup for an <a href="https://azure.microsoft.com/en-us/documentation/articles/web-sites-publish-source-control/?ref=stevemichelotti.com">Azure Web App with Continuous Deployment from a Github </a>repository. This automatically deploys the latest code anytime I check-in to my Github repository. I never actually had to use the &quot;Deploy to Azure&quot; button.</p>
<h2 id="ghosttheme">Ghost Theme</h2>
<p>With Ghost in place, the next item on my list was to get a good theme. There are a few great sites for getting Ghost themes including the Ghost Marketplace and <a href="http://www.allghostthemes.com/?ref=stevemichelotti.com">All Ghost Themes</a>. I got a paid theme from All Ghost Themes.</p>
<h2 id="azurecdn">Azure CDN</h2>
<p>Moving my static files to the Azure CDN was one of the most important aspects of moving my blog. The Azure CDN allows me to have better performance by serving content to consumers from geographic locations closest to them.</p>
<p>First I <a href="https://msdn.microsoft.com/en-us/library/azure/gg680307.aspx?ref=stevemichelotti.com">mapped my CDN to a custom domain</a> - cdn.stevemichelotti.com.</p>
<p>Then I created the following containers in my blob/CDN storage:</p>
<p><img src="http://cdn.stevemichelotti.com/images/ghost-blog-cdn-containers.png" alt loading="lazy"></p>
<p>I then used Gulp to optimize (i.e., concat/uglify) various JavaScript and CSS files. <em>Finally</em> being able to have full control over every piece of content in my blog enabled me to get my <a href="https://chrome.google.com/webstore/detail/yslow/ninejjcohidippngpapiilnmkgllmakh?utm_source=chrome-app-launcher-info-dialog">YSlow</a> score up to a very respectable level.</p>
<p>Using the CDN I&apos;ll also be able to optimize expires headers of static content. Additionally, if I ever move my blog again, I won&apos;t have to transfer images since they&apos;re now all on my own custom domain for my CDN.</p>
<h2 id="movingcontent">Moving Content</h2>
<p>Moving content was more of a pain than I anticipated. There are several tools to migrate to Ghost from other platforms (e.g., <a href="http://blogger2ghost.herokuapp.com/?ref=stevemichelotti.com">Blogger</a>, <a href="https://wordpress.org/plugins/ghost/faq/?ref=stevemichelotti.com">WordPress</a>, and <a href="http://tumblr-to-ghost.herokuapp.com/?ref=stevemichelotti.com">Tumblr</a>). However, none of them worked with my existing platform. So it was a somewhat manual process for me that consisted of:</p>
<ol>
<li>Writing a local Node script that iterated through all my old posts and converted them to Markdown using <a href="http://heckyesmarkdown.com/?ref=stevemichelotti.com">Heck Yes Markdown</a>.</li>
<li>Save each Markdown file locally, including the title and publish date in each file name.</li>
<li>Import all Markdown files into Ghost using <a href="http://support.ghost.org/import-and-export-my-ghost-blog-settings-and-data/?ref=stevemichelotti.com">the Admin tool</a>.</li>
</ol>
<p>For the most part, this worked fine. But I did have to go through many old posts to ensure the formatting was satisfactory.</p>
<h2 id="disqusforcomments">Disqus for Comments</h2>
<p><a href="https://disqus.com/?ref=stevemichelotti.com">Disqus</a> is a strong standard for a comment engine for blogs these days. The setup process was quick and integrating this into my blog was very straight forward.</p>
<h2 id="appinsightsandgoogleanalytics">App Insights and Google Analytics</h2>
<p>I&apos;ve currently got both <a href="http://azure.microsoft.com/en-us/services/application-insights/?ref=stevemichelotti.com">Application Insights</a> (from Microsoft) and <a href="http://www.google.com/analytics/?ref=stevemichelotti.com">Google Analytics</a> integrated. Perhaps I&apos;ll consolidate to just one of them in the future - but for now I&apos;m going to use both.</p>
<h2 id="codesyntaxhighlighting">Code Syntax Highlighting</h2>
<p>There are a number of good choices for code syntax highlighting. In the past, my choices were limited because of some lack of control I had on my previous platform. Since I now have full control, I decided to use <a href="http://alexgorbatchev.com/SyntaxHighlighter/?ref=stevemichelotti.com">SyntaxHighlighter</a>. It is extremely full-featured including line numbers and line highlighting support. It also supports brushes for a number of different languages.</p>
<h2 id="feedburner">Feedburner</h2>
<p>Originally, I thought Feedburner would be a trivial step - after all, all I needed to do was to go into my Feedburner account and burn the feed for my new blog location. However, I did run into <em>one</em> complication. I wanted to make sure I supported feed auto-discovery but including:</p>
<pre><code>&lt;link rel=&quot;alternate&quot; type=&quot;application/rss+xml&quot; title=&quot;Steve Michelotti&quot; href=&quot;http://feeds.feedburner.com/SteveMichelotti&quot; /&gt;
</code></pre>
<p>However, Ghost was hard-coded to include:</p>
<pre><code>&lt;link rel=&quot;alternate&quot; type=&quot;application/rss+xml&quot; title=&quot;Steve Michelotti&quot; href=&quot;http://stevemichelotti.com/rss/&quot; /&gt;
</code></pre>
<p>The good news was that, since I have now have full control over the source code for my blog, I could fix this myself. I simply went into ghost_head.js in the core code and removed this line of code:</p>
<pre class="brush: js;">
head.push(&apos;&lt;link rel=&quot;alternate&quot; type=&quot;application/rss+xml&quot; title=&quot;&apos; + 
    title  + &apos;&quot; href=&quot;&apos; + config.urlFor(&apos;rss&apos;, null, true) + &apos;&quot; /&gt;&apos;);
</pre>
<p>Then I manually added the correct <code>&lt;link&gt;</code> element to the <code>&lt;head&gt;</code> section of my site.</p>
<h2 id="whataboutlivewriter">What about Live Writer?</h2>
<p>It seems everyone on the Windows platform loves using Windows Live Writer to author blog posts (including me). But Live Writer doesn&apos;t support Markdown. Frankly, this is just fine with me. I think people in general that love Markdown like writing directly in Markdown. Also, in place of Live Writer, I now use <a href="http://markdownpad.com/?ref=stevemichelotti.com">MarkdownPad</a> to author posts offline. MarkdownPad is the best Markdown editor I&apos;ve seen and I love using it.</p>
<h2 id="conclusion">Conclusion</h2>
<p>So far I&apos;m very happy with the move. Time will tell - but it&apos;s great to finally be on a modern blogging platform with complete control over the code and environment.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Customize Authentication Header in SwaggerUI using Swashbuckle]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p><a href="http://swagger.io/?ref=stevemichelotti.com">Swagger</a> has quickly established itself as an important tool for building Web API&apos;s for any platform. Swagger enables interactive documentation and client SDK generation/discoverability. One of the most frequently used Swagger tools is <a href="http://swagger.io/swagger-ui/?ref=stevemichelotti.com">Swagger UI</a>. Swagger UI provides automatically generated HTML assets that give you automatic documentation</p>]]></description><link>https://stevemichelotti.com/customize-authentication-header-in-swaggerui-using-swashbuckle/</link><guid isPermaLink="false">5d06ef6be9c13100173aebf3</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Fri, 26 Jun 2015 17:01:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p><a href="http://swagger.io/?ref=stevemichelotti.com">Swagger</a> has quickly established itself as an important tool for building Web API&apos;s for any platform. Swagger enables interactive documentation and client SDK generation/discoverability. One of the most frequently used Swagger tools is <a href="http://swagger.io/swagger-ui/?ref=stevemichelotti.com">Swagger UI</a>. Swagger UI provides automatically generated HTML assets that give you automatic documentation and even an online test tool. To see Swagger UI in action, check out their <a href="http://petstore.swagger.io/?ref=stevemichelotti.com">demo page</a>.</p>
<p>Although Swagger/Swagger UI can be used for any platform, the <a href="https://github.com/domaindrivendev/Swashbuckle?ref=stevemichelotti.com">Swashbuckle</a> library makes integrating Swagger UI into a .NET Web API app a breeze. In fact, Azure API Apps specifically leverage Swagger via Swashbuckle to provide the metadata for Azure API apps.</p>
<p>Most of the out of the box features of Swagger work great. However, there are times when you need to customize this behavior. For example, by default Swagger UI gives you a textbox for for the &quot;API key&quot;. When you execute the request, it simply puts this API key into a query string variable called &quot;api_key&quot; as shown in the screen shot:</p>
<p><img src="http://cdn.stevemichelotti.com/images/swagger-default-api-key.png" alt loading="lazy"></p>
<p>But what do you do if you need some other type of authentication? Perhaps you need Basic Auth or suppose the API key needs to be sent in an HTTP header rather than the query string.</p>
<p>Most of the online resources I found, suggest that you should simply replace the default web page by copying the original and making the changes you need. While it&apos;s great to have this type of flexibility, the problem is that it makes it harder to keep up when new versions come out. You&apos;d have to continually update your code (that you&apos;ve now taken ownership of) each time a new version comes out.</p>
<p>What I want to do instead is to simply inject some JavaScript into the page to make this happen. This JavaScript needs to:</p>
<ul>
<li>Add two textboxes to the page (one for username and one for password)</li>
<li>Remove/hide the existing textbox for API key</li>
<li>Set the Password Authorization (basic auth) header to use these values</li>
</ul>
<p>Here are the steps to make that happen.</p>
<p>First, make sure the &quot;Swashbuckle&quot; and &quot;Swashbuckle.Core&quot; NuGet packages are added to your project. If you&apos;re working in an Azure API app, they&apos;ll already be added for you.</p>
<p>Next, add a new JavaScript file to your project. I&apos;ll put this file in a folder called &quot;CustomContent&quot;:</p>
<p><img src="http://cdn.stevemichelotti.com/images/swashbuckle-basic-auth.png" alt loading="lazy"></p>
<p>Right-click this new JavaScript file and select &quot;Properties&quot;. Then change its &quot;Build Action&quot; to &quot;Embedded Resource&quot;.</p>
<p>Next, go to the SwaggerConfig.cs file that was added to your project when you added the Swashbuckle NuGet package. This file contains a ton of commented code &#x2013; this is just to show you example configuration code that you can use. If you scroll down that file, you&apos;ll see a commented method call to the InjectJavaScript() method. Right below that, I can now add this line of C# code:</p>
<pre class="brush: js;">
c.InjectJavaScript(thisAssembly, &quot;SwashbuckleCustomAuth.CustomContent.basic-auth.js&quot;);
</pre>
<p>Pay close attention to this string. The default namespace for my project happens to be &quot;SwashbuckleCustomAuth&quot;. Then I&apos;ve put this JavaScript file in a folder called &quot;CustomContent&quot;. Finally, I give the name of the JS file. Make sure you&apos;ve got this string correct so it will find the embedded resource properly.</p>
<p>Next, let&apos;s have a look at the JavaScript code that we need to put in to basic-auth.js:</p>
<pre class="brush: js;">
(function () {
    $(function () {
        var basicAuthUI =
            &apos;&lt;div class=&quot;input&quot;&gt;&lt;input placeholder=&quot;username&quot; id=&quot;input_username&quot; name=&quot;username&quot; type=&quot;text&quot; size=&quot;10&quot;&gt;&lt;/div&gt;&apos; +
            &apos;&lt;div class=&quot;input&quot;&gt;&lt;input placeholder=&quot;password&quot; id=&quot;input_password&quot; name=&quot;password&quot; type=&quot;password&quot; size=&quot;10&quot;&gt;&lt;/div&gt;&apos;;
        $(basicAuthUI).insertBefore(&apos;#api_selector div.input:last-child&apos;);
        $(&quot;#input_apiKey&quot;).hide();
&amp;nbsp;
        $(&apos;#input_username&apos;).change(addAuthorization);
        $(&apos;#input_password&apos;).change(addAuthorization);
    });
&amp;nbsp;
    function addAuthorization() {
        var username = $(&apos;#input_username&apos;).val();
        var password = $(&apos;#input_password&apos;).val();
        if (username &amp;amp;&amp;amp; username.trim() != &quot;&quot; &amp;amp;&amp;amp; password &amp;amp;&amp;amp; password.trim() != &quot;&quot;) {
            var basicAuth = new SwaggerClient.PasswordAuthorization(&apos;basic&apos;, username, password);
            window.swaggerUi.api.clientAuthorizations.add(&quot;basicAuth&quot;, basicAuth);
            console.log(&quot;authorization added: username = &quot; + username + &quot;, password = &quot; + password);
        }
    }
})();
</pre>
<p>jQuery is already part of the HTML page so we can leverage that here. I use JavaScript to create the two new textboxes I need &#x2013; then I insert them as the last child of the &quot;api_selector&quot; form that contains these textboxes in the header. I then hide the default api key textbox since we won&apos;t be using it. The next thing we need to ensure is that we&apos;re setting the header correctly when the values in these textboxes change. For this we can use the SwaggerClient.PasswordAuthorization which is built into the Swagger JavaScript library. This code will ensure it&apos;s added to the request:</p>
<p><img src="http://cdn.stevemichelotti.com/images/swagger-basic-auth.png" alt loading="lazy"></p>
<p>In the screen shot above, I put in a username of &quot;steve&quot; and a password of &quot;123&quot;. This time when I invoke the request, you can see an Authorization header for Basic auth being sent in the HTTP request headers. Problem solved.</p>
<p>Alternatively, let&apos;s say that instead of Basic Auth, you want the API key sent in the header rather than in the query string. Furthermore, let&apos;s say you need that API header to be called &quot;my-cool-api-key&quot;. In that case, we don&apos;t need to add any of our own textboxes but just repurpose the API key text box that is already there. We can add a new JavaScript file and make it an embedded resource in the exact same way that I&apos;ve previously described. The JavaScript for that will look like this:</p>
<pre class="brush: js;">
(function () {
    $(function () {
        $(&apos;#input_apiKey&apos;).off();
        $(&apos;#input_apiKey&apos;).on(&apos;change&apos;, function () {
            var key = this.value;
            if (key &amp;&amp; key.trim() !== &apos;&apos;) {
                swaggerUi.api.clientAuthorizations.add(&quot;key&quot;, new SwaggerClient.ApiKeyAuthorization(&quot;my-cool-api-key&quot;, key, &quot;header&quot;));
            }
        });
    });
})();
</pre>
<p>One other point that can sometimes lead to confusion. You might notice that the Swashbuckle configuration contains methods like this:</p>
<pre class="brush: csharp;">
c.BasicAuth(&quot;basic&quot;).Description(&quot;Basic HTTP Authentication&quot;);
</pre>
<p>At first glance you might think/hope that will make the UI do the Basic Authentication for you &#x2013; but it doesn&apos;t. That simply changes the metadata that comes out of the Swagger schema that <em>informs</em> the user what type of authentication is being used. But if you actually want the Swagger UI to correctly execute the appropriate authentication scheme, follow the steps in this blog post if you&apos;re working in .NET projects.</p>
<p>A sample solution containing these techniques (minus the <em>actual</em> authentication) can be <a href="http://cdn.stevemichelotti.com/code/SwashbuckleCustomAuth.zip?ref=stevemichelotti.com">downloaded here</a>.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[MVP Virtual Conference Videos]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>A few weeks ago I was one of the presenters for the <a href="http://mvp.microsoft.com/en-us/virtualconference.aspx?ref=stevemichelotti.com">Microsoft MVP Virtual Conference</a>. All of the videos for the conference have recently been <a href="https://channel9.msdn.com/Events/MVP-Virtual-Conference/MVP-Virtual-Conference-Americas-2015?ref=stevemichelotti.com">published to Channel 9</a>.</p>
<p>There were many great talks at this virtual conference and I encourage you to <a href="https://channel9.msdn.com/Events/MVP-Virtual-Conference/MVP-Virtual-Conference-Americas-2015?ref=stevemichelotti.com">check them out</a>. My presentation was:</p>]]></description><link>https://stevemichelotti.com/mvp-virtual-conference-videos/</link><guid isPermaLink="false">5d06ef6be9c13100173aebf2</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Fri, 19 Jun 2015 17:02:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>A few weeks ago I was one of the presenters for the <a href="http://mvp.microsoft.com/en-us/virtualconference.aspx?ref=stevemichelotti.com">Microsoft MVP Virtual Conference</a>. All of the videos for the conference have recently been <a href="https://channel9.msdn.com/Events/MVP-Virtual-Conference/MVP-Virtual-Conference-Americas-2015?ref=stevemichelotti.com">published to Channel 9</a>.</p>
<p>There were many great talks at this virtual conference and I encourage you to <a href="https://channel9.msdn.com/Events/MVP-Virtual-Conference/MVP-Virtual-Conference-Americas-2015?ref=stevemichelotti.com">check them out</a>. My presentation was: <a href="https://channel9.msdn.com/Events/MVP-Virtual-Conference/MVP-Virtual-Conference-Americas-2015/Dev1-Supercharge-your-Development-with-Azure-Websites?ref=stevemichelotti.com">Supercharge your Development with Azure Web Apps</a> (formerly known as Azure Websites). My talk consisted of 12 different demos as I covered the following topics on Azure Web Apps:</p>
<ul>
<li>Continuous Deployment</li>
<li>Configuration</li>
<li>Auto Scaling</li>
<li>Monitoring</li>
<li>Operations</li>
<li>SCM Admin Site</li>
<li>Extensions</li>
<li>Web Jobs</li>
<li>Azure CLI</li>
<li>Multi-Platform with Node</li>
<li>Analytics</li>
<li>Customizing the Portal</li>
</ul>
<!--kg-card-end: markdown-->]]></content:encoded></item><item><title><![CDATA[Create Node Task for Visual Studio Code]]></title><description><![CDATA[<!--kg-card-begin: markdown--><p>I love the new <a href="https://code.visualstudio.com/?ref=stevemichelotti.com">Visual Studio Code</a> editor/IDE. It&apos;s fast, simple, lightweight, and an overall pleasure to work with. I love being able to just &quot;open a folder&quot; and work with files directly &#x2013; all while getting great intellisense.</p>
<p>One feature that is particular interesting</p>]]></description><link>https://stevemichelotti.com/create-node-task-for-visual-studio-code/</link><guid isPermaLink="false">5d06ef6be9c13100173aeb27</guid><dc:creator><![CDATA[Steve Michelotti]]></dc:creator><pubDate>Wed, 20 May 2015 19:18:00 GMT</pubDate><content:encoded><![CDATA[<!--kg-card-begin: markdown--><p>I love the new <a href="https://code.visualstudio.com/?ref=stevemichelotti.com">Visual Studio Code</a> editor/IDE. It&apos;s fast, simple, lightweight, and an overall pleasure to work with. I love being able to just &quot;open a folder&quot; and work with files directly &#x2013; all while getting great intellisense.</p>
<p>One feature that is particular interesting to me is the ability to run <a href="https://code.visualstudio.com/Docs/tasks?ref=stevemichelotti.com">Tasks</a> from the IDE. These tasks can be anything from running gulp commands, to MSBuild, to most anything you can think of. Given that JavaScript &#x2013; and Node in particular &#x2013; is one of the sweet spots, I assumed that there would be a built-in task to run a file with Node. After all, there is <a href="https://code.visualstudio.com/Docs/nodejs?ref=stevemichelotti.com">native support for debugging Node code</a>. But one thing I often like to do is to simple run a single file with node from the command line:</p>
<pre><code>&gt; node index.js
</code></pre>
<p>So I don&apos;t need debugging. I want to execute Node against whatever file I have opened at the moment. It turns out this was not built-in &#x2013; but the good news is that it was not difficult to add the functionality.</p>
<p>First, <strong>Ctrl+Shift+P</strong> to bring up the Command Palette. Then you want to type &quot;<strong>Configure Task Runner</strong>&quot;. That will open a &quot;tasks.json&quot; file which it will create in a local &quot;.settings&quot; directory. Inside there is a default TypeScript task along with a bunch of commented out tasks to show example of running on commands like gulp, MSBuild, etc. (and yes, just pretend that JSON actually has comments). You can remove everything in this file and just add:</p>
<pre class="brush: js;">
 {
 	&quot;version&quot;: &quot;0.1.0&quot;,
 	&quot;command&quot;: &quot;node&quot;,
 	&quot;isShellCommand&quot;: true,
 	&quot;args&quot;: [&quot;${file}&quot;]
 }
</pre>
<p>One thing to notice is the this file allows tokens such as <strong>${file}</strong> to represent the current opened file. Now Save the &quot;tasks.json&quot; file (if you don&apos;t already have Auto-Save turned on) and return back to any of your JavaScript files. Now you can just bring up the Command Palette again and type &quot;<strong>Run Task</strong>&quot; &#x2013; hit <strong>ENTER</strong> and &quot;<strong>node</strong>&quot; (which is what we named our task) will be the only thing in the list. Run that and the Output window will appear in split screen the the resulting output of your node file.</p>
<p><img src="http://cdn.stevemichelotti.com/images/vs-code-node-task.png" alt loading="lazy"></p>
<p>Yes, of course, I can just go over to a console window and type: &quot;<strong>node index.js</strong>&quot; as I&apos;ve always traditionally done. But this makes it even easier/faster and let&apos;s me stay within my IDE. Plus, this will always work against whatever file I happen to have opened at the time.</p>
<p>One bizarre thing I&apos;ve found is that I don&apos;t (yet) see any way to <a href="http://stackoverflow.com/q/30046411/352246?ref=stevemichelotti.com">add multiple tasks to the &quot;tasks.json&quot; file</a> - there does seem to be a way to add multiple tasks for a single command, but not multiple tasks for different commands. Hopefully, this will be a feature that is addressed in new versions of VS Code.</p>
<!--kg-card-end: markdown-->]]></content:encoded></item></channel></rss>