<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jon Hilton</title>
    <description>The latest articles on DEV Community by Jon Hilton (@jonhilt).</description>
    <link>https://dev.to/jonhilt</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F18691%2F90201748-88aa-4d2d-9ae4-e6925d5fdc1b.jpg</url>
      <title>DEV Community: Jon Hilton</title>
      <link>https://dev.to/jonhilt</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jonhilt"/>
    <language>en</language>
    <item>
      <title>Edit and Replay your network requests, direct from the browser</title>
      <dc:creator>Jon Hilton</dc:creator>
      <pubDate>Mon, 07 Sep 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/jonhilt/edit-and-replay-your-network-requests-direct-from-the-browser-4dn4</link>
      <guid>https://dev.to/jonhilt/edit-and-replay-your-network-requests-direct-from-the-browser-4dn4</guid>
      <description>&lt;p&gt;You know how it goes; you build your shiny new feature using Blazor, React, Vue, &lt;code&gt;&amp;lt;insert framework here&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You test locally; everything works as it should.&lt;/p&gt;

&lt;p&gt;Then you push to production and…&lt;/p&gt;

&lt;p&gt;… everything is broken!&lt;/p&gt;

&lt;p&gt;Any number of things can break your app in prod but one of the biggies is data coming back (or being posted) via your network calls which doesn’t match what you expected.&lt;/p&gt;

&lt;p&gt;For some time we’ve been able to inspect those network requests via the browser’s Dev Tools, to see what’s really going on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tCBpo8Lb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/Network%2520Requests.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tCBpo8Lb--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/Network%2520Requests.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can inspect the request, check what parameters are being sent across, then look at the response and inspect the resulting data to see why your feature might be working the way it is.&lt;/p&gt;

&lt;p&gt;But, what if you want to play with that request, tweak it’s parameters, or just replay the request, without having to drive everything from the UI?&lt;/p&gt;

&lt;p&gt;Microsoft Edge now includes an &lt;strong&gt;Edit and Replay&lt;/strong&gt; feature comes in, and it’s pretty darn useful.&lt;/p&gt;

&lt;p&gt;So long as you’re using the new (actually really good) Chromium version of Edge, you can enable the shiny new &lt;strong&gt;Network Console&lt;/strong&gt; for your browser.&lt;/p&gt;

&lt;p&gt;With that, head over to any network request in the Dev Tools, right-click and select &lt;strong&gt;Edit and Replay&lt;/strong&gt; and…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1lbOx-Rq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/EditableRequests.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1lbOx-Rq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/EditableRequests.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Network Console springs into life and shows you the request, including things like Query parameters, the request Body and Auth tokens etc.&lt;/p&gt;

&lt;p&gt;From here you can click &lt;strong&gt;Send&lt;/strong&gt; to replay the request, at which point you can easily inspect the response for that request…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ceJly448--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/Response.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ceJly448--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/Response.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then you can download the resulting json, or just edit the request and try again.&lt;/p&gt;

&lt;p&gt;There are of course other ways to achieve similar results. I’ve been a big fan of a tool called Insomnia in recent years.&lt;/p&gt;

&lt;p&gt;But, for testing authenticated requests it was always a bit of a pain to locate the JWT auth token, copy it and paste it across to Insomnia, then set up the request etc.&lt;/p&gt;

&lt;p&gt;Now, with a couple of clicks you can replay requests right there in the browser, Auth tokens and everything!&lt;/p&gt;

&lt;p&gt;It’s worth noting this is an &lt;strong&gt;“Experimental Feature&lt;/strong&gt; so expect a few bugs here and there, but overall this looks like a big step forward for testing your client applications.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.microsoft.com/en-gb/microsoft-edge/devtools-guide-chromium/whats-new/2020/06/devtools#edit-and-replay-requests-with-the-network-console"&gt;Check out this post by Microsoft for all the details&lt;/a&gt; (including how to enable this in Edge).&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Make a responsive Navbar with Blazor and Tailwind?</title>
      <dc:creator>Jon Hilton</dc:creator>
      <pubDate>Tue, 04 Aug 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/jonhilt/make-a-responsive-navbar-with-blazor-and-tailwind-52c</link>
      <guid>https://dev.to/jonhilt/make-a-responsive-navbar-with-blazor-and-tailwind-52c</guid>
      <description>&lt;p&gt;You’ve no doubt seen the “hamburger” icon many, many times.&lt;/p&gt;

&lt;p&gt;For example, head over to &lt;a href="https://tailwindcss.com/docs/installation/"&gt;Tailwind’s docs&lt;/a&gt;, and you’ll see a full menu (on the left) if you’re using a big enough screen…&lt;/p&gt;

&lt;p&gt;Knock that down to a smaller resolution though and the menu disappears, to be replaced by an icon in the top-right corner.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dLGprO8_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/ResponsiveNav.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dLGprO8_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/ResponsiveNav.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you click that the nav menu appears…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4zeiuSp8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/MenuOpen.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4zeiuSp8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/MenuOpen.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Build it using Blazor
&lt;/h2&gt;

&lt;p&gt;So how can you build this using Tailwind and Blazor?&lt;/p&gt;

&lt;p&gt;Well it turns out most of the work here is actually the CSS, with just a tiny bit of code needed with Blazor to make it work.&lt;/p&gt;

&lt;p&gt;In preparation I’ve:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Already configured this example Blazor app to use Tailwind CSS&lt;/li&gt;
&lt;li&gt;Removed all references to Bootstrap&lt;/li&gt;
&lt;li&gt;Modified the &lt;strong&gt;MainLayout.razor&lt;/strong&gt; and &lt;strong&gt;NavMenu.razor&lt;/strong&gt; components to use &lt;code&gt;flex&lt;/code&gt; as a simple starting layout for our example application&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;MainLayout.razor&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex flex-col min-h-screen"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;NavMenu/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"p-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    @Body
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

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



&lt;p&gt;&lt;strong&gt;NavMenu.razor&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"p-6 bg-blue-500 text-white"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Your site!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

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



&lt;p&gt;Which renders this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hKbCkRJR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/StartingPoint.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hKbCkRJR--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/StartingPoint.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Mobile first
&lt;/h2&gt;

&lt;p&gt;Let’s be well-behaved developers and focus on making this work for mobile first!&lt;/p&gt;

&lt;p&gt;We want to display a hamburger icon in the top-right of the nav bar.&lt;/p&gt;

&lt;p&gt;First, we can add the icon to the existing HTML to see how it looks…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Your site!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"h-6 w-6 fill-current"&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 24 24"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;fill-rule=&lt;/span&gt;&lt;span class="s"&gt;"evenodd"&lt;/span&gt;
&lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"M4 5h16a1 1 0 0 1 0 2H4a1 1 0 1 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2z"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

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



&lt;p&gt;Which renders:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aNKJPNi2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/HamburgerInTheWrongPlace.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aNKJPNi2--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/HamburgerInTheWrongPlace.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To pull that over to the right we can use CSS’s ever-mysterious (but actually really useful) &lt;code&gt;flexbox&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"p-6 bg-blue-500 text-white"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex justify-between"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Your site!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;

 &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"h-6 w-6 fill-current"&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 24 24"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;fill-rule=&lt;/span&gt;&lt;span class="s"&gt;"evenodd"&lt;/span&gt;
 &lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"M4 5h16a1 1 0 0 1 0 2H4a1 1 0 1 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2z"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

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



&lt;p&gt;By wrapping everything in a &lt;code&gt;div&lt;/code&gt; we can use &lt;code&gt;flex&lt;/code&gt; and &lt;code&gt;justify-between&lt;/code&gt; to arrange all the elements within our &lt;code&gt;nav&lt;/code&gt; along the x-axis, with equal space between them.&lt;/p&gt;

&lt;p&gt;This essentially pulls the first item to the left, and the next item to the right.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--A2EYMMGz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/ArrangedHamburger.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--A2EYMMGz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/ArrangedHamburger.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now what about the actual menu with all our nav items?&lt;/p&gt;

&lt;p&gt;In this mode (mobile) we want to show a simple list below the nav bar itself (eventually we’ll trigger this by clicking the hamburger icon).&lt;/p&gt;

&lt;p&gt;I’ll add the nav links at the end of the &lt;strong&gt;NavMenu.razor&lt;/strong&gt; component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"p-6 bg-blue-500 text-white"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex justify-between"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Your site!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"h-6 w-6 fill-current"&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 24 24"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;fill-rule=&lt;/span&gt;&lt;span class="s"&gt;"evenodd"&lt;/span&gt;
&lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"M4 5h16a1 1 0 0 1 0 2H4a1 1 0 1 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2z"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex flex-col"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;NavLink&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/NavLink&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;NavLink&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/counter"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Counter&lt;span class="nt"&gt;&amp;lt;/NavLink&amp;gt;&lt;/span&gt;
   &lt;span class="nt"&gt;&amp;lt;NavLink&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/fetchdata"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Fetch Data&lt;span class="nt"&gt;&amp;lt;/NavLink&amp;gt;&lt;/span&gt;
 &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

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



&lt;p&gt;&lt;code&gt;flex&lt;/code&gt; comes in handy again here. Without this and &lt;code&gt;flex-col&lt;/code&gt; our nav links would appear next to each other.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;flex-col&lt;/code&gt; this switches to them being arranged in a column, vertically like so.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XHqS4IoM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/VerticalLinks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XHqS4IoM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/VerticalLinks.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now this is OK, but we probably want to make it look a little nicer. The following tweaks are entirely subjective depending on what you’re aiming for but here’s may attempt at tidying this up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-blue-500 text-white"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex items-center justify-between p-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Your site!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;button&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"h-6 w-6 fill-current"&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 24 24"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;fill-rule=&lt;/span&gt;&lt;span class="s"&gt;"evenodd"&lt;/span&gt;
&lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"M4 5h16a1 1 0 0 1 0 2H4a1 1 0 1 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2z"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
     &lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex flex-col bg-gray-700 px-4 py-2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;NavLink&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/NavLink&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;NavLink&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/counter"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Counter&lt;span class="nt"&gt;&amp;lt;/NavLink&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;NavLink&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/fetchdata"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Fetch Data&lt;span class="nt"&gt;&amp;lt;/NavLink&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

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



&lt;h3&gt;
  
  
  Adjust padding
&lt;/h3&gt;

&lt;p&gt;I moved the padding from the outermost &lt;code&gt;div&lt;/code&gt; to the ‘inner’ &lt;code&gt;div&lt;/code&gt;, and knocked it down from &lt;code&gt;p-6&lt;/code&gt; to &lt;code&gt;p-4&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The problem with the padding being on the outermost &lt;code&gt;div&lt;/code&gt; is it affects everything, including the &lt;code&gt;ul&lt;/code&gt; list of links. This means you can’t get the links to go right up to the edges of the div, because of the padding.&lt;/p&gt;

&lt;p&gt;So I scrapped that and added padding to the &lt;code&gt;div&lt;/code&gt; which contains the main heading and hamburger icon instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adjust vertical alignment of heading and hamburger
&lt;/h3&gt;

&lt;p&gt;I used &lt;code&gt;items-center&lt;/code&gt; to make sure the heading and hamburger icon are vertically centered in their containing div.&lt;/p&gt;

&lt;h3&gt;
  
  
  Added some style to the nav links
&lt;/h3&gt;

&lt;p&gt;Finally I’ve given the &lt;code&gt;ul&lt;/code&gt; a background colour and a little padding (&lt;code&gt;px-4&lt;/code&gt; to make sure the links line up with the heading in the div above).&lt;/p&gt;

&lt;p&gt;And here’s how it looks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1XB_-zHV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/NiceLinks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1XB_-zHV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/NiceLinks.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Not too shabby!&lt;/p&gt;

&lt;h2&gt;
  
  
  Make the links appear or disappear on click
&lt;/h2&gt;

&lt;p&gt;Before we go any further let’s make those links only appear when you click the icon.&lt;/p&gt;

&lt;p&gt;First we’ll add a little C# code to &lt;strong&gt;NavMenu.razor&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;@code&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;_menuVisible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;ToggleMenu&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;_menuVisible&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;!&lt;/span&gt;&lt;span class="n"&gt;_menuVisible&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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



&lt;p&gt;With this we can toggle a boolean &lt;code&gt;_menuVisible&lt;/code&gt; on and off.&lt;/p&gt;

&lt;p&gt;Now to use that in the markup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-blue-500 text-white"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"flex items-center justify-between p-4"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;h1&amp;gt;&lt;/span&gt;Your site!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"ToggleMenu"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"h-6 w-6 fill-current"&lt;/span&gt; &lt;span class="na"&gt;viewBox=&lt;/span&gt;&lt;span class="s"&gt;"0 0 24 24"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;path&lt;/span&gt; &lt;span class="na"&gt;fill-rule=&lt;/span&gt;&lt;span class="s"&gt;"evenodd"&lt;/span&gt;
&lt;span class="na"&gt;d=&lt;/span&gt;&lt;span class="s"&gt;"M4 5h16a1 1 0 0 1 0 2H4a1 1 0 1 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2zm0 6h16a1 1 0 0 1 0 2H4a1 1 0 0 1 0-2z"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
@{
  var menuVisibleClass = _menuVisible ? "" : "hidden";
}

&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"@($"&lt;/span&gt;&lt;span class="na"&gt;flex&lt;/span&gt; &lt;span class="na"&gt;flex-col&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="na"&gt;menuVisibleClass&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="na"&gt;bg-gray-700&lt;/span&gt; &lt;span class="na"&gt;px-4&lt;/span&gt; &lt;span class="na"&gt;py-2&lt;/span&gt;&lt;span class="err"&gt;")"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;NavLink&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Home&lt;span class="nt"&gt;&amp;lt;/NavLink&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;NavLink&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/counter"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Counter&lt;span class="nt"&gt;&amp;lt;/NavLink&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;NavLink&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/fetchdata"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Fetch Data&lt;span class="nt"&gt;&amp;lt;/NavLink&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

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



&lt;p&gt;I’ve added an &lt;code&gt;onclick&lt;/code&gt; event handler to the button. When it’s clicked &lt;code&gt;ToggleMenu&lt;/code&gt; will be invoked.&lt;/p&gt;

&lt;p&gt;The second part may look slightly over-complicated, but with good reason!&lt;/p&gt;

&lt;p&gt;Rather than use a conditional &lt;code&gt;@if&lt;/code&gt; to control visiblity of the menu I’ve opted to use CSS classes instead.&lt;/p&gt;

&lt;p&gt;This is so we can override the class on larger screens (to permanently show the menu).&lt;/p&gt;

&lt;p&gt;Here’s how it works:&lt;/p&gt;

&lt;p&gt;First I’ve defined a string variable to store the value &lt;code&gt;hidden&lt;/code&gt; if &lt;code&gt;_menuVisible&lt;/code&gt; is &lt;code&gt;false&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This will be used to hide the menu.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;menuVisibleClass&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;_menuVisible&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"hidden"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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



&lt;p&gt;I’ve then used a little string interpolation to include that class in the CSS class definition for our &lt;code&gt;ul&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="s"&gt;$"flex flex-col &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;menuVisibleClass&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt; bg-gray-700 px-4 py-2"&lt;/span&gt;

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





&lt;blockquote&gt;
&lt;p&gt;To use C# when declaring values for an HTML attribute in Razor you can wrap the entire thing in brackets preceded by an @ symbol.&lt;/p&gt;


&lt;pre class="highlight html"&gt;&lt;code&gt; class="@( $"border {blue}" )"
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;This makes it possible to declare C# in the value; In this example rendering the current value of blue as part of the CSS class attribute value.&lt;/p&gt;
&lt;/blockquote&gt;



&lt;h2&gt;
  
  
  Handle non-mobile
&lt;/h2&gt;

&lt;p&gt;With that we’re almost done!&lt;/p&gt;

&lt;p&gt;Now to make those links appear automatically (and the icon disappear) on larger screens.&lt;/p&gt;

&lt;p&gt;We could just duplicate the &lt;code&gt;ul&lt;/code&gt; and have a different one for larger resolutions, but this duplication is bound to catch us out when we come to add more links to the nav.&lt;/p&gt;

&lt;p&gt;Instead, we can use some CSS trickery to re-use the exact same &lt;code&gt;ul&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We’re aiming for the nav links to look like this on ‘medium’ and above resolutions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--E4W5kM-c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/MediumOrAboveNav.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--E4W5kM-c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/MediumOrAboveNav.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here’s how to break this down.&lt;/p&gt;

&lt;p&gt;First, if we use &lt;code&gt;flex&lt;/code&gt; for the outer div we can make the existing div (which includes the heading and hamburger icon) appear side-by-side with our &lt;code&gt;ul&lt;/code&gt; nav links (on medium or higher screen resolutions).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-blue-500 text-white md:flex md:justify-between md:items-center"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- existing content --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

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



&lt;p&gt;But this looks a little, er, broken…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D-kDKogc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/MissingLinks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D-kDKogc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/MissingLinks.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The links are still hidden&lt;/li&gt;
&lt;li&gt;The hamburger icon is squashed up to the heading&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The good news is, everything still looks right on mobile, but on larger resolutions we’re not quite there yet.&lt;/p&gt;

&lt;p&gt;We don’t actually need to see the hamburger icon at this resolution so we can hide that with a simple &lt;code&gt;md:hidden&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;onclick=&lt;/span&gt;&lt;span class="s"&gt;"ToggleMenu"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"md:hidden"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- button svg --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;

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



&lt;p&gt;We can also make our &lt;code&gt;ul&lt;/code&gt; visible with a couple of &lt;code&gt;flex&lt;/code&gt; classes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"@($"&lt;/span&gt;&lt;span class="na"&gt;flex&lt;/span&gt; &lt;span class="na"&gt;flex-col&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="na"&gt;menuVisibleClass&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="na"&gt;bg-gray-700&lt;/span&gt; &lt;span class="na"&gt;px-4&lt;/span&gt; &lt;span class="na"&gt;py-2&lt;/span&gt; &lt;span class="na"&gt;md:flex&lt;/span&gt; &lt;span class="na"&gt;md:flex-row&lt;/span&gt;&lt;span class="err"&gt;")"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- links --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

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



&lt;p&gt;&lt;code&gt;md:flex md:flex-row&lt;/code&gt; take care of making our links visible and displayed horizontally in a row.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--cvdAEPTn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/WrongBackgroundColor.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cvdAEPTn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/BlazorWASMByExample/WrongBackgroundColor.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Almost there! Now to make the &lt;code&gt;ul&lt;/code&gt; background colour disappear on medium screens and above.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;md:bg-transparent&lt;/code&gt; should do it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ul&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"@($"&lt;/span&gt;&lt;span class="na"&gt;flex&lt;/span&gt; &lt;span class="na"&gt;flex-col&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;&lt;span class="na"&gt;menuVisibleClass&lt;/span&gt;&lt;span class="err"&gt;}&lt;/span&gt; &lt;span class="na"&gt;bg-gray-700&lt;/span&gt; &lt;span class="na"&gt;px-4&lt;/span&gt; &lt;span class="na"&gt;py-2&lt;/span&gt; &lt;span class="na"&gt;md:flex&lt;/span&gt; &lt;span class="na"&gt;md:flex-row&lt;/span&gt; &lt;span class="na"&gt;md:bg-transparent&lt;/span&gt;&lt;span class="err"&gt;")"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- links --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/ul&amp;gt;&lt;/span&gt;

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



&lt;h2&gt;
  
  
  That’s a wrap!
&lt;/h2&gt;

&lt;p&gt;There it is! We have a fully responsive nav bar with a teeny tiny bit of C# to make everything tick.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hH0kBBhg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://jonhilton.net/img/responsiveNav.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hH0kBBhg--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://jonhilton.net/img/responsiveNav.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;flex&lt;/code&gt; carries a bit of a learning curve, but Tailwind makes it easier to pick up and use.&lt;/p&gt;

&lt;p&gt;Once you get the basics (mainly whether to use &lt;code&gt;flex-row&lt;/code&gt; or &lt;code&gt;flex-col&lt;/code&gt; and justifying items) there’ll be no stopping you!&lt;/p&gt;

&lt;p&gt;The ability to to target common device resolutions using the breakpoint name as a prefix (&lt;code&gt;md:&lt;/code&gt; in the examples above) makes it straightforward to employ different styles at different breakpoints.&lt;/p&gt;

&lt;p&gt;Blazor has a small, but very useful role, to handle the click events for the ‘hamburger’ icon, translating that into a simple boolean to determine whether the menu should be visible or not (on smaller screens).&lt;/p&gt;

&lt;h3&gt;
  
  
  Next Steps
&lt;/h3&gt;

&lt;p&gt;There are of course many more tweaks we could make from here. Here are a couple of ideas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make the links change appearance when you hover over them using Tailwind’s &lt;code&gt;hover:&lt;/code&gt; pseudo class prefix&lt;/li&gt;
&lt;li&gt;Use a second icon for when the nav links are visible on mobile, maybe an x to hide them again&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>Blazor by Example - Build a simple markdown editor</title>
      <dc:creator>Jon Hilton</dc:creator>
      <pubDate>Mon, 27 Jan 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/jonhilt/blazor-by-example-build-a-simple-markdown-editor-40j2</link>
      <guid>https://dev.to/jonhilt/blazor-by-example-build-a-simple-markdown-editor-40j2</guid>
      <description>&lt;p&gt;Blazor promises to empower C# developers to build modern web applications quickly, using a language and ecosystem they already know and understand.&lt;/p&gt;

&lt;p&gt;So let’s see how this stacks up with a real-world requirement; building a simple markdown editor.&lt;/p&gt;

&lt;p&gt;It’s hard to imagine a world without Markdown these days.&lt;/p&gt;

&lt;p&gt;For everything from blog posts, to github issues and self published ebooks, Markdown has cemented its position has a convenient way to edit plain text, whilst maintaining some control over the ultimate format and appearance of your work.&lt;/p&gt;

&lt;p&gt;Today’s Blazor example centres on building a markdown text editor.&lt;/p&gt;

&lt;p&gt;The requirement is to provide a text box which accepts markdown and generates a live preview of the resulting HTML.&lt;/p&gt;

&lt;p&gt;Here’s how I’d approach building something like this in Blazor:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create the basic HTML structure (rows, columns etc)&lt;/li&gt;
&lt;li&gt;Add the essential HTML elements (textarea in this case)&lt;/li&gt;
&lt;li&gt;Add bindings to make the textarea value sync with a field/property in the component&lt;/li&gt;
&lt;li&gt;Implement code to convert the markdown to HTML&lt;/li&gt;
&lt;li&gt;Render the HTML on screen&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Create the initial structure and elements
&lt;/h1&gt;

&lt;p&gt;Let’s start with some basic HTML structure….&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Editor.razor&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;@page "/markdown"

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Editor goes here
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Preview goes here
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

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



&lt;p&gt;I’m sticking to Bootstrap here because my CSS kinda sucks…&lt;/p&gt;

&lt;p&gt;This gives us a simple two column layout for our page; now to add a &lt;code&gt;textarea&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;@page "/markdown"

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form-control"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        Preview goes here
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

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



&lt;p&gt;Run this and you’ll see a text area, nothing very interesting going on yet…&lt;/p&gt;

&lt;h1&gt;
  
  
  Bind your inputs to something
&lt;/h1&gt;

&lt;p&gt;Now we’re ready to take the next step; we need to take whatever is entered into the &lt;code&gt;textarea&lt;/code&gt; and store it in our component’s state.&lt;/p&gt;

&lt;p&gt;For this, we can use properties and Blazor’s binding syntax. We just need to declare a couple of attributes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form-control"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;bind-value=&lt;/span&gt;&lt;span class="s"&gt;"Body"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;bind-value:event=&lt;/span&gt;&lt;span class="s"&gt;"oninput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;

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



&lt;p&gt;These attributes tell Blazor to bind the value of &lt;code&gt;textarea&lt;/code&gt; to a property called &lt;code&gt;Body&lt;/code&gt; and to update &lt;code&gt;Body&lt;/code&gt; whenever the value of our &lt;code&gt;textarea&lt;/code&gt; changes.&lt;/p&gt;

&lt;p&gt;The result? &lt;code&gt;Body&lt;/code&gt; will always reflects the contents of the &lt;code&gt;textarea&lt;/code&gt;. Whenever the value of &lt;code&gt;textarea&lt;/code&gt; changes, &lt;code&gt;Body&lt;/code&gt; will be instantly updated with the new value.&lt;/p&gt;

&lt;p&gt;Now you might have noticed we haven’t created a &lt;code&gt;Body&lt;/code&gt; property anywhere yet.&lt;/p&gt;

&lt;p&gt;Whilst it is possible to write all your Blazor UI logic in &lt;code&gt;@code&lt;/code&gt; blocks in the razor files themselves, I generally prefer to put that code into a separate class.&lt;/p&gt;

&lt;p&gt;Let’s create a component base class for our component and declare the &lt;code&gt;Body&lt;/code&gt; property in there:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Editor.razor.cs&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MarkdownEditorBase&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ComponentBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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



&lt;p&gt;Now we just need to update our component markup to inherit this component base class and, whilst we’re here, add a binding to render the current value of &lt;code&gt;Body&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This way we can check that ‘Body’ definitely does update as we change the contents of the &lt;code&gt;textarea&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;@page "/markdown"
@inherits MarkdownEditorBase

&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"row"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form-control"&lt;/span&gt; 
            &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;bind-value=&lt;/span&gt;&lt;span class="s"&gt;"Body"&lt;/span&gt; 
            &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;bind-value:event=&lt;/span&gt;&lt;span class="s"&gt;"oninput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        @Body
    &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

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



&lt;p&gt;Run this, type something into the textarea and you’ll see an instant preview of what you typed.&lt;/p&gt;

&lt;p&gt;But, hold the phone, I promised an all-singing and dancing HTML preview…&lt;/p&gt;

&lt;p&gt;As it stands, if you throw markdown at this &lt;code&gt;textarea&lt;/code&gt; you’re just going to see that markdown in the preview, exactly as you typed it…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--R7no5dkt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-25-blazor-example-markdown-editor/2020-01-25-21-26-47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--R7no5dkt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-25-blazor-example-markdown-editor/2020-01-25-21-26-47.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  From markup to HTML
&lt;/h1&gt;

&lt;p&gt;Happily, we don’t need to expend much effort to get HTML from this markup, we can employ the excellent Markdig .NET Markdown processor to do it for us.&lt;/p&gt;

&lt;p&gt;Bring in the NuGet package…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="nf"&gt;Install-Package&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;Markdig&lt;/span&gt;&lt;span class="w"&gt;

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



&lt;p&gt;&lt;a href="https://github.com/lunet-io/markdig"&gt;Markdig&lt;/a&gt; will take any text and process the Markdown for us, spitting HTML out the other end.&lt;/p&gt;

&lt;p&gt;Let’s add a new &lt;code&gt;Preview&lt;/code&gt; property to our component which will invoke Markdig every time we request its value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Markdig&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.AspNetCore.Components&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MarkdownEditorBase&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ComponentBase&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Body&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Empty&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Preview&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Markdown&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ToHtml&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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



&lt;p&gt;I’ve also updated &lt;code&gt;Body&lt;/code&gt; so it will always have an initial empty string value (rather than being &lt;code&gt;null&lt;/code&gt; which would trip Markdig up).&lt;/p&gt;

&lt;p&gt;Now we can update our component markup to render this preview instead of &lt;code&gt;Body&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"form-control"&lt;/span&gt; 
        &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;bind-value=&lt;/span&gt;&lt;span class="s"&gt;"Body"&lt;/span&gt; 
        &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;bind-value:event=&lt;/span&gt;&lt;span class="s"&gt;"oninput"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/textarea&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    @Preview
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

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



&lt;p&gt;Run this now and tada…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--coo-EFrB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-25-blazor-example-markdown-editor/2020-01-25-21-49-13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--coo-EFrB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-25-blazor-example-markdown-editor/2020-01-25-21-49-13.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I mean, it’s HTML, but not the glorious preview we were hoping for.&lt;/p&gt;

&lt;p&gt;Ideally we’d want to actually render the HTML and get a sense of how our content is shaping up; seeing the raw HTML itself isn’t much use.&lt;/p&gt;

&lt;p&gt;Luckily Blazor has one more trick up its sleeve; rendering raw markup.&lt;/p&gt;

&lt;p&gt;By default Blazor won’t just push this markup out for your browser to render; after all, if you blindly accept code you don’t own and run it in the browser, any number of bad things could happen!&lt;/p&gt;

&lt;p&gt;But if you’re happy with the risks, you can force Blazor to spit this code out raw and let the Browser do as it pleases.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"col-6"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    @((MarkupString) Preview)
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;

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



&lt;p&gt;Now we’re talking.&lt;/p&gt;

&lt;p&gt;Type markdown in on the left, get HTML rendered on the right.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--EmwqOFIG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-25-blazor-example-markdown-editor/2020-01-25-22-04-24.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--EmwqOFIG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-25-blazor-example-markdown-editor/2020-01-25-22-04-24.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Sometimes as a developer you come up against a requirement which you expect to be complex (and take ages) to build, and every now and again it turns out to be easier than you thought.&lt;/p&gt;

&lt;p&gt;In this case, building a simple markdown editor using Blazor turned out to be pretty straightforward.&lt;/p&gt;

&lt;p&gt;Markdig does all the heavy lifting and a tiny amount of Blazor binding syntax handles the rest.&lt;/p&gt;

&lt;p&gt;Check out the &lt;a href="https://github.com/jonhilt/BlazorExamples/tree/master/Pages/MarkdownEditor"&gt;complete source code for this example here&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>6 Blazor component libraries to speed up your development</title>
      <dc:creator>Jon Hilton</dc:creator>
      <pubDate>Mon, 20 Jan 2020 00:00:00 +0000</pubDate>
      <link>https://dev.to/jonhilt/6-blazor-component-libraries-to-speed-up-your-development-15i6</link>
      <guid>https://dev.to/jonhilt/6-blazor-component-libraries-to-speed-up-your-development-15i6</guid>
      <description>&lt;p&gt;.NET Developers have a long history with component libraries.&lt;/p&gt;

&lt;p&gt;If you’re not familiar with the concept, these are collections of components you can drop into your application when you want a certain bit of UI functionality for your app.&lt;/p&gt;

&lt;p&gt;If you’re thinking tables, accordians and toggle buttons, you’re on the right track.&lt;/p&gt;

&lt;p&gt;But why do such things exist? Why would you want to use a third party component in favour of “rolling your own”?&lt;/p&gt;

&lt;p&gt;I can think of a few reasons.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSS
&lt;/h2&gt;

&lt;p&gt;I work with a couple of developers who “get” CSS. They seem to have an innate ability to create beautiful looking web applications; bending the browser to their will with a couple of well crafted lines.&lt;/p&gt;

&lt;p&gt;I, on the other hand, can easily lose hours to a “simple bit of CSS”, fighting the syntax every step of the way, labouring to slay the CSS beast only to find it works perfectly on my Chrome desktop but resembles an early Geocities page when I view it on a mobile!&lt;/p&gt;

&lt;p&gt;If component libraries can “do CSS” for me, I’m in…&lt;/p&gt;

&lt;h2&gt;
  
  
  Rapid prototyping
&lt;/h2&gt;

&lt;p&gt;Even if you might want (or need) to write your own UI components, starting with a library can be a real time saver when it comes to spinning up a prototype or V1 of an application.&lt;/p&gt;

&lt;p&gt;If you can drop a grid into your application, complete with paging, sorting, filtering etc. vs spending hours/days building one yourself, it’s got to be tempting to go with the first option (not least so you can focus on your business logic and flow).&lt;/p&gt;

&lt;h2&gt;
  
  
  Battle tested
&lt;/h2&gt;

&lt;p&gt;All the big component libraries also have the benefit of being pretty well battle-tested.&lt;/p&gt;

&lt;p&gt;Once a company like Telerik has released a few iterations of a grid component you’d imagine it will have gone through a hefty amount of testing (both internally and by customers) so it’s pretty low risk to use it in your own application (and you’d expect it to be cross browser compatible which is a significant time saver).&lt;/p&gt;

&lt;h1&gt;
  
  
  Exploring Blazor’s component libaries
&lt;/h1&gt;

&lt;p&gt;So, if those are some of the benefits, what are the component library options for Blazor (as we move inexorably towards an official Blazor WASM release)?&lt;/p&gt;

&lt;p&gt;The following list is almost certainly incomplete so feel free to hit me up on Twitter (&lt;a class="comment-mentioned-user" href="https://dev.to/jonhilt"&gt;@jonhilt&lt;/a&gt;
) or leave a comment and point out everything I’ve missed!&lt;/p&gt;

&lt;h2&gt;
  
  
  Radzen Blazor Components
&lt;/h2&gt;

&lt;p&gt;Site: &lt;a href="https://razor.radzen.com/"&gt;https://razor.radzen.com/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Pricing: Free for commercial use&lt;br&gt;&lt;br&gt;
Server: Yes&lt;br&gt;&lt;br&gt;
WASM: Yes&lt;/p&gt;

&lt;p&gt;Radzen Blazor Components is a free set of 40+ native Blazor UI controls.&lt;/p&gt;

&lt;p&gt;It includes all the basic form controls you’d hope (Date Pickers etc) along with data grids and containers such as accordians and tabs.&lt;/p&gt;

&lt;p&gt;It doesn’t handle data visualisation e.g. charts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VF8rY4sa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-16-blazor-component-libraries/2020-01-16-11-05-55.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VF8rY4sa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-16-blazor-component-libraries/2020-01-16-11-05-55.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  SyncFusion Blazor UI Components
&lt;/h2&gt;

&lt;p&gt;Site: &lt;a href="https://blazor.syncfusion.com/"&gt;https://blazor.syncfusion.com/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Pricing: &lt;strong&gt;Free community license&lt;/strong&gt; or $995 /developer 1st year&lt;br&gt;&lt;br&gt;
Server: Yes&lt;br&gt;&lt;br&gt;
WASM: Yes&lt;/p&gt;

&lt;p&gt;There are a number of component libraries which, on the face of it, seem “expensive” and SyncFusion is one of them.&lt;/p&gt;

&lt;p&gt;Admittedly, value is in the eye of the bolder, and $995 a year might be peanuts compared to the productivity gains you’ll make as a reasonable sized company with more than a handful of developers.&lt;/p&gt;

&lt;p&gt;However, it also pays to read the small print, and in this case they offer a community license based on you matching conditions laid out &lt;a href="https://www.syncfusion.com/products/communitylicense"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Namely that you’re an individual or company with less than $1 million USD in annual gross revenue and 5 or fewer developers.&lt;/p&gt;

&lt;p&gt;In terms of the components themselves, they have a comprehensive collection including small components such as Date Pickers all the way up to rich text editors, word processors and file managers.&lt;/p&gt;

&lt;p&gt;Various options for data visualization are also included (charts etc).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qIfuAByX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-16-blazor-component-libraries/2020-01-16-10-50-45.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qIfuAByX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-16-blazor-component-libraries/2020-01-16-10-50-45.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Telerik UI for Blazor
&lt;/h2&gt;

&lt;p&gt;Site: &lt;a href="https://www.telerik.com/blazor-ui"&gt;https://www.telerik.com/blazor-ui&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Pricing: $899/developer perpetual license&lt;br&gt;&lt;br&gt;
Server: Yes&lt;br&gt;&lt;br&gt;
WASM: Yes&lt;/p&gt;

&lt;p&gt;Doesn’t boast quite so many components as SyncFusion, but has the basics covered with Date Pickers, Buttons, Grids etc.&lt;/p&gt;

&lt;p&gt;Also includes various charts for data visualisation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yi-7jzt5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-16-blazor-component-libraries/2020-01-16-11-00-20.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yi-7jzt5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-16-blazor-component-libraries/2020-01-16-11-00-20.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  DevExpress Blazor Components
&lt;/h2&gt;

&lt;p&gt;Site: &lt;a href="https://www.devexpress.com/blazor/"&gt;https://www.devexpress.com/blazor/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Pricing: Free “for a limited time”&lt;br&gt;&lt;br&gt;
Server: Yes (I think) - couldn’t see this listed explicitly anywhere…&lt;br&gt;&lt;br&gt;
WASM: Yes (I think) - as above&lt;/p&gt;

&lt;p&gt;DevExpress’s library is currently free. However, the big caveat here is in the wording which includes the sentence “for a limited time”, so it’s hard to know where they’ll go with pricing in the future.&lt;/p&gt;

&lt;p&gt;In terms of the library itself, it includes essentials like Data Grids, Charts, and various Editors (date pickers etc).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Q-Mwxh_T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-16-blazor-component-libraries/2020-01-16-10-59-18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Q-Mwxh_T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-16-blazor-component-libraries/2020-01-16-10-59-18.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Blazored libraries and components
&lt;/h2&gt;

&lt;p&gt;Site: &lt;a href="https://github.com/Blazored"&gt;https://github.com/Blazored&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Pricing: Free&lt;br&gt;&lt;br&gt;
Server: Yes&lt;br&gt;&lt;br&gt;
WASM: Yes (I think)&lt;/p&gt;

&lt;p&gt;This is a collection of GitHub repositories including various components such as Modals, Text Editors, Toast popups etc.&lt;/p&gt;

&lt;p&gt;It offers some useful time savers such as Typeahead to offer up auto complete suggestions as you type into a text input.&lt;/p&gt;

&lt;p&gt;Chris Sainty is behind this (I thoroughly recommend his &lt;a href="https://chrissainty.com/"&gt;excellent Blazor blog&lt;/a&gt;) and the code is all open source (available on GitHub).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qoFrf2Aa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-16-blazor-component-libraries/2020-01-16-11-17-36.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qoFrf2Aa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-16-blazor-component-libraries/2020-01-16-11-17-36.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Blazorise
&lt;/h2&gt;

&lt;p&gt;Site: &lt;a href="https://blazorise.com/"&gt;https://blazorise.com/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Pricing: Free&lt;br&gt;&lt;br&gt;
Server: Yes&lt;br&gt;&lt;br&gt;
WASM: Yes&lt;/p&gt;

&lt;p&gt;Built on frameworks such as Bootstrap, Bulma and Material, Blazorise offers a decent number of components ready for you to drop into your Blazor apps.&lt;/p&gt;

&lt;p&gt;You can use any of the free provided CSS frameworks, leaving you free to stick with Bootstrap if that’s what you generally use, or look at the alternatives (Bulma or Material).&lt;/p&gt;

&lt;p&gt;Again the basics are all there (Editors, Buttons, Grids etc) and they have a Chart component to boot.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HlDQNf-3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-16-blazor-component-libraries/2020-01-16-11-17-06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HlDQNf-3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2020-01-16-blazor-component-libraries/2020-01-16-11-17-06.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>blazor</category>
    </item>
    <item>
      <title>Use Blazor in your existing ASP.NET Core 3.x application</title>
      <dc:creator>Jon Hilton</dc:creator>
      <pubDate>Wed, 04 Dec 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/jonhilt/use-blazor-in-your-existing-asp-net-core-3-x-application-1g0l</link>
      <guid>https://dev.to/jonhilt/use-blazor-in-your-existing-asp-net-core-3-x-application-1g0l</guid>
      <description>&lt;p&gt;Starting with ASP.NET Core 3.0, you can add Blazor components to your existing ASP.NET Core (MVC, Razor Pages) application.&lt;/p&gt;

&lt;p&gt;This is a great way to test the ground with Blazor, without chucking everything you have in the bin and starting over!&lt;/p&gt;

&lt;p&gt;Here’s how to do it using ASP.NET Core 3.1 (released December 3rd 2019).&lt;/p&gt;

&lt;p&gt;In your existing ASP.NET Core 3 app, you’ll need to update &lt;code&gt;ConfigureServices&lt;/code&gt; in startup.cs to add all the services required for Blazor Server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddServerSideBlazor&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

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



&lt;p&gt;Now you can add the &lt;code&gt;MapBlazorHub&lt;/code&gt; call in &lt;code&gt;Configure&lt;/code&gt; to register the Blazor Hub endpoint (which Blazor Server uses to communicate with the browser).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseEndpoints&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoints&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;   
    &lt;span class="n"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapRazorPages&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// existing endpoints&lt;/span&gt;
    &lt;span class="n"&gt;endpoints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;MapBlazorHub&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;                
&lt;span class="p"&gt;});&lt;/span&gt;

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



&lt;p&gt;Almost there; at this point your ASP.NET Core application is ready to process and render Blazor components.&lt;/p&gt;

&lt;p&gt;Now you just need to render one!&lt;/p&gt;

&lt;p&gt;You can add a &lt;strong&gt;.razor&lt;/strong&gt; component somewhere in your application (for now I just put mine in the Pages folder and called it &lt;strong&gt;HelloWorld.razor&lt;/strong&gt; ).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;@page&lt;/span&gt; &lt;span class="s"&gt;"/Hello"&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;HelloWorld&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;Hello&lt;/span&gt; &lt;span class="n"&gt;@Name&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt; &lt;span class="n"&gt;@onclick&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"Toggle"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Toggle&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="n"&gt;@code&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Jon"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;Toggle&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Jon"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Susan"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Jon"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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



&lt;p&gt;Finally, you can take an existing page like &lt;strong&gt;Index.cshtml&lt;/strong&gt; and add some code to render your component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;@page&lt;/span&gt;
&lt;span class="n"&gt;@model&lt;/span&gt; &lt;span class="n"&gt;IndexModel&lt;/span&gt;
&lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;ViewData&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s"&gt;"Title"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Home page"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt; &lt;span class="n"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"~/_framework/blazor.server.js"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;script&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;component&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"typeof(HelloWorld)"&lt;/span&gt; &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"ServerPrerendered"&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;

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



&lt;p&gt;First we’ve added a reference to &lt;strong&gt;blazor.server.js&lt;/strong&gt; ; this is required for Blazor to communicate between the browser and your application. You’ll find this script is automatically made available by your ASP.NET Core application.&lt;/p&gt;

&lt;p&gt;Then we’ve used the component tag helper (new in ASP.NET Core 3.1) to render the &lt;code&gt;HelloWorld&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;If you’re using ASP.NET Core 3.0, you’ll need to use &lt;code&gt;HTML.RenderComponentAsync&lt;/code&gt; instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;@(await Html.RenderComponentAsync&lt;span class="nt"&gt;&amp;lt;HelloWorld&amp;gt;&lt;/span&gt;(RenderMode.ServerPrerendered))

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



&lt;p&gt;Spin this up in the browser now and you’ll see your component, rendered in all its glory (in your Razor page!)&lt;/p&gt;

&lt;p&gt;However, the &lt;strong&gt;Toggle&lt;/strong&gt; button won’t work until we take one more step.&lt;/p&gt;

&lt;p&gt;Add an &lt;strong&gt;_Imports.razor&lt;/strong&gt; file to your &lt;strong&gt;Pages&lt;/strong&gt; folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;@using System.Net.Http
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Routing
@using Microsoft.JSInterop
@using Microsoft.AspNetCore.Components.Web

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



&lt;p&gt;With that, your application has everything it needs to support Razor components; the &lt;code&gt;HelloWorld&lt;/code&gt; component renders, and clicking the button changes the &lt;code&gt;Name&lt;/code&gt; and re-renders the markup accordingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Move the Blazor script to shared layout
&lt;/h2&gt;

&lt;p&gt;Now this works, but we can improve things further.&lt;/p&gt;

&lt;p&gt;Currently, a SignalR connection will be opened up every time you navigate to &lt;strong&gt;Index.cshtml&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This might be less than desirable, not least because you get a small flash of content appearing every time this connection is made.&lt;/p&gt;

&lt;p&gt;So a better option is probably to put this in your application’s Layout page (assuming you have one).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shared/_Layout.cshtml&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="c"&gt;&amp;lt;!-- other scripts --&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"~/_framework/blazor.server.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;

@RenderSection("Scripts", required: false) &lt;span class="c"&gt;&amp;lt;!-- existing code --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;

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



&lt;h2&gt;
  
  
  What is RenderMode?
&lt;/h2&gt;

&lt;p&gt;In this example I used &lt;code&gt;RenderMode.ServerPrerendered&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You might be wondering what this means.&lt;/p&gt;

&lt;p&gt;Essentially, there are three ways to render Blazor components in a Razor View or Page.&lt;/p&gt;

&lt;h3&gt;
  
  
  Static
&lt;/h3&gt;

&lt;p&gt;ASP.NET will render the component at the same time as the rest of the page and return static html to your browser.&lt;/p&gt;

&lt;h3&gt;
  
  
  Server
&lt;/h3&gt;

&lt;p&gt;ASP.NET will render a marker for the component, and return that with the rest of the page, at which point Blazor (running in the browser) will open up its socket connection to the server, render the component and then update the DOM in the browser to display the component.&lt;/p&gt;

&lt;h3&gt;
  
  
  ServerPrerendered
&lt;/h3&gt;

&lt;p&gt;A kind of “best of both worlds”.&lt;/p&gt;

&lt;p&gt;ASP.NET will render and return the component’s markup with the rest of the page. Then it will act the same as Server mode whereby it will include a marker for the component and set up a Blazor connection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which RenderMode?
&lt;/h2&gt;

&lt;p&gt;Each of these three options has trade-offs, but the main thing to watch out for is performance and how they work with Seach Engines.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;RenderMode.Static&lt;/code&gt; your page is rendered entirely, in one call to the server.&lt;/p&gt;

&lt;p&gt;This means, if a search engine comes along and requests your page, it will get the entire thing back (including your component) and can index it accordingly.&lt;/p&gt;

&lt;p&gt;You can see this for yourself in the browser; hit your page and notice how the component markup is returned as part of the page response (this is using Firefox Dev Tools)…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QAS4cRVE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/5-use-blazor-in-existing-app/2019-12-04-11-15-12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QAS4cRVE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/5-use-blazor-in-existing-app/2019-12-04-11-15-12.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, the component is essentially “non-interactive” at this point. So clicking the &lt;strong&gt;Toggle&lt;/strong&gt; button won’t do anything at all.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GT0HcAF7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/5-use-blazor-in-existing-app/2019-12-04-10-55-11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GT0HcAF7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/5-use-blazor-in-existing-app/2019-12-04-10-55-11.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;RenderMode.Server&lt;/code&gt; mode, the opposite is true.&lt;/p&gt;

&lt;p&gt;Your component won’t be rendered in the initial response when you visit the page:&lt;/p&gt;

&lt;p&gt;Instead, Blazor will kick in after your page is rendered and then render the component (via the socket connection it opens up with your server).&lt;/p&gt;

&lt;p&gt;Now the &lt;strong&gt;Toggle&lt;/strong&gt; button works, but search engines won’t “see” that component markup when they index the page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--yjYPJt4J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://jonhilton.net/img/blazor-week/ServerRenderMode.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--yjYPJt4J--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://jonhilton.net/img/blazor-week/ServerRenderMode.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, &lt;code&gt;RenderMode.ServerPrerendered&lt;/code&gt; does both.&lt;/p&gt;

&lt;p&gt;You get the initial markup for the component in the initial page response, then Blazor kicks in and opens up its socket connection for further interactions with the component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oW797nWm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://jonhilton.net/img/blazor-week/ServerPrerendered.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oW797nWm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://jonhilton.net/img/blazor-week/ServerPrerendered.gif" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;Adding Blazor to your existing ASP.NET Core 3 app turns out to be relatively straightforward; you can give Blazor a try, without affecting the rest of your application and see for yourself whether you find it a productive way to build your application’s user interface.&lt;/p&gt;

&lt;p&gt;Your simplest next step might be to take some small part of your UI (like a table, list, or some other read-only component) and try building that as a Blazor component.&lt;/p&gt;

&lt;p&gt;That way, you can quickly get a feel for how building components differs from building pages or views before moving on to more “interactive” components (using callbacks etc).&lt;/p&gt;

</description>
    </item>
    <item>
      <title>But, which flavor of ASP.NET?</title>
      <dc:creator>Jon Hilton</dc:creator>
      <pubDate>Wed, 13 Nov 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/jonhilt/but-which-flavor-of-asp-net-536c</link>
      <guid>https://dev.to/jonhilt/but-which-flavor-of-asp-net-536c</guid>
      <description>&lt;h1&gt;
  
  
  Two developers walk into a bar…
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Developer:&lt;/strong&gt; Hey, I want to build a web application and I’m looking to use Microsoft technologies&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; Great, you’ll want to explore ASP.NET then&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developer:&lt;/strong&gt; Sounds good, how do I get started?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; Well, which “flavor” of ASP.NET do you want to use?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developer:&lt;/strong&gt; What do you mean?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; Well, there’s MVC or Razor Pages for server-side development, unless you fancy trying Blazor in which case you can use Blazor Server, or if you’re happy to go really cutting edge there’s always Blazor Client?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developer:&lt;/strong&gt; Um, OK, well which is best?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; um…&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developer:&lt;/strong&gt; Oh, and I’ve heard a lot of people recommending React, is that an option?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; (to bartender) I think we’re going to need another drink…&lt;/p&gt;

&lt;h1&gt;
  
  
  Making sense of the options
&lt;/h1&gt;

&lt;p&gt;This is a GREAT time to be a web developer using MS technologies, but (and it’s a big but) it sure is confusing when you’re just getting started and you’re pelted with so many choices…&lt;/p&gt;

&lt;p&gt;They say knowledge is power, so let’s break these options down…&lt;/p&gt;

&lt;h3&gt;
  
  
  Server-side or Client
&lt;/h3&gt;

&lt;p&gt;Before we get into specifics, we should consider the two broad categories these options fall into.&lt;/p&gt;

&lt;p&gt;Either, your application will run on the &lt;strong&gt;server&lt;/strong&gt; , where the server takes on the job of retrieving data from a database, applying business logic, mangling data and markup together before spewing the results out as HTML (for your browser to render).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--TPwCjHVy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-25-where-to-start/2019-11-11-14-11-26.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TPwCjHVy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-25-where-to-start/2019-11-11-14-11-26.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or, you’ll build a &lt;strong&gt;client-side&lt;/strong&gt; application where all the presentation markup and logic runs in the browser (typically javascript).&lt;/p&gt;

&lt;p&gt;With this model, the browser makes an initial request to load the application’s HTML, CSS and javascript, and to render the initial (home) page.&lt;/p&gt;

&lt;p&gt;Thereafter, the client application makes calls to your server when it requires data, or to execute business logic on the backend. The server returns data (typically JSON) which your client-side application mangles together with markup and displays in the browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lbLZmOYt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-25-where-to-start/2019-11-11-14-05-13.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lbLZmOYt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-25-where-to-start/2019-11-11-14-05-13.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One way or another, your data and markup get mangled together, either on the server, or on the client (browser).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;But then, there is another option (kinda),&lt;/p&gt;

&lt;p&gt;I know, I did say there were two options but… Blazor Server sits somewhere between the two, with most of the work done on the server but an atypical approach to making requests and receiving responses. More on that shortly.&lt;/p&gt;

&lt;p&gt;Before we get there, where do the various flavors of ASP.NET fit into this picture?&lt;/p&gt;

&lt;h3&gt;
  
  
  ASP.NET MVC (Server-side)
&lt;/h3&gt;

&lt;p&gt;With MVC, all the grunt work is done on the server and the browser is given straightforward HTML to render.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--McOkrKhI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-25-where-to-start/2019-11-11-16-31-34.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--McOkrKhI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-25-where-to-start/2019-11-11-16-31-34.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The user attempts to navigate to a URL in the browser.&lt;/p&gt;

&lt;p&gt;The browser pings this requests over to the server.&lt;/p&gt;

&lt;p&gt;ASP.NET MVC takes over, forwards the request to the relevant controller.&lt;/p&gt;

&lt;p&gt;With MVC you use Controllers and return Views with data, like this…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class UserController {

    public IActionResult List(){
        var data = //some data from your database
        return View(data)
    }

}

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



&lt;p&gt;At this point, ASP.NET MVC renders your &lt;strong&gt;Razor View&lt;/strong&gt; (by convention, that would be &lt;code&gt;List.cshtml&lt;/code&gt; in the above example), using the data its been given. It then generates standard HTML and returns this to the browser.&lt;/p&gt;

&lt;p&gt;The browser then renders this HTML.&lt;/p&gt;

&lt;p&gt;When your user clicks buttons etc, the browser makes a request to the server, which forwards it to an ASP.NET Controller, which re-renders and returns the entire view.&lt;/p&gt;

&lt;p&gt;Rinse and Repeat.&lt;/p&gt;

&lt;h3&gt;
  
  
  ASP.NET Razor Pages (Server-side)
&lt;/h3&gt;

&lt;p&gt;Razor Pages (not to be confused with Razor Views, which are used in MVC) also does all its User Interface (UI) rendering on the server and returns HTML to the browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8J_eTo48--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-25-where-to-start/2019-11-11-16-36-21.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8J_eTo48--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-25-where-to-start/2019-11-11-16-36-21.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;At a high level, this looks just like MVC. The main difference is how you organise your presentation logic and markup.&lt;/p&gt;

&lt;p&gt;With Razor Pages you create &lt;strong&gt;Pages&lt;/strong&gt; and update the Page Model with your data, like this…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class UserList : PageModel
{
    public List&amp;lt;User&amp;gt; Users { get; set; }

    public void OnGet()
    {
        var users = //some data from your database
        Users = users;
    }
}

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



&lt;p&gt;Just like MVC, when your users click buttons etc, the browser makes a request to the server which re-renders and returns the entire page.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://jonhilton.net/razor-pages-or-mvc-a-quick-comparison/"&gt;MVC vs Razor Pages&lt;/a&gt; for a more detailed comparison of the two approaches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Blazor Server (Server-side/Client-side hybrid)
&lt;/h3&gt;

&lt;p&gt;Blazor server is the new kid in town, and does something surprising.&lt;/p&gt;

&lt;p&gt;With Blazor, when you launch your application, it retrieves some initial HTML, CSS and javascript.&lt;/p&gt;

&lt;p&gt;But then it pulls a rabbit out of a hat and does something none of the other options in this list do; it opens up a socket connection to your server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H6iRX9Si--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-25-where-to-start/2019-11-11-15-52-00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H6iRX9Si--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-25-where-to-start/2019-11-11-15-52-00.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, when your users interact with your application, instead of requesting entire pages from the server, Blazor forwards things like button clicks etc. to the server over this socket connection.&lt;/p&gt;

&lt;p&gt;The server then has a look at what event occurred (for example which button was clicked), runs whatever code you’ve written to handle that event, figures out which parts of the UI have changed, and sends a small diff (outlining which elements have changed) over the socket connection, back to the browser.&lt;/p&gt;

&lt;p&gt;The part of your Blazor application which runs in the browser then process this diff and updates the DOM elements accordingly.&lt;/p&gt;

&lt;p&gt;So the bulk of the processing (retrieving data, mangling this together with markup) happens on the server, and small diffs are transmitted to the browser so it knows which parts of the user interface to update.&lt;/p&gt;

&lt;p&gt;With Blazor, you write your User Interface as a series of components, which can be composed together to form your application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@page "/users"

&amp;lt;h3&amp;gt;Users&amp;lt;/h3&amp;gt;

@foreach (var user in _users)
{
    &amp;lt;User name="@user.Name"/&amp;gt;
}

@code {
    private List&amp;lt;User&amp;gt; _users;

    protected override async Task OnInitializedAsync()
    {
        _users = //some data from your database
    }
}

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



&lt;h3&gt;
  
  
  Blazor WebAssembly (Client-side)
&lt;/h3&gt;

&lt;p&gt;Blazor WebAssembly is still in preview but takes the Blazor story one step further.&lt;/p&gt;

&lt;p&gt;With this, when your user visits your application, the entire Blazor application is sent to the browser as compiled C# DLLs. A compact version of the .NET runtime is also shipped to the browser.&lt;/p&gt;

&lt;p&gt;Something called Web Assembly (which is baked into all modern browsers) bootstraps the .NET runtime and loads your assemblies (remember, all of this is happening in the browser).&lt;/p&gt;

&lt;p&gt;Thereafter, the Blazor WebAssembly runtime handles things like DOM updates and sending API calls to your server.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--6IsziRlL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-25-where-to-start/2019-11-11-16-21-47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6IsziRlL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-25-where-to-start/2019-11-11-16-21-47.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this mode, all your presentation logic actually executes in the browser, so button clicks and your handling code are executed and the UI updated in your browser, with no need to contact your server.&lt;/p&gt;

&lt;p&gt;Well, until you need data.&lt;/p&gt;

&lt;p&gt;Then, your Blazor WebAssembly application can make AJAX requests to your server, retrieve data (typically as JSON), mix this data up with your component markup (this is done in the browser) and render the resulting HTML.&lt;/p&gt;

&lt;p&gt;People are excitied about this option because it opens the door to writing your web applications using C#, but still getting all the benefits of running a SPA (single page application) in the browser (performance, seamless showing and hiding of components etc.)&lt;/p&gt;

&lt;p&gt;With Blazor WebAssembly, you write your User Interface using the exact same component model as Blazor Server; the main difference being how you retrieve data, via an AJAX call rather than a direct call to a service or some such…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@page "/users"

&amp;lt;h3&amp;gt;Users&amp;lt;/h3&amp;gt;

@foreach (var user in _users)
{
    &amp;lt;User name="@user.Name"/&amp;gt;
}

@code {
    private User[] _users;

    protected override async Task OnInitializedAsync()
    {
        _users = await Http.GetJsonAsync&amp;lt;User[]&amp;gt;("users/list")
    }
}

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



&lt;h3&gt;
  
  
  Web API + JS SPA
&lt;/h3&gt;

&lt;p&gt;Similar to Blazor WebAssembly, you can create a client-side web application using a JS framework like React, Angular or Vue.&lt;/p&gt;

&lt;p&gt;Now when your user visits your application, an initial request is made to retrieve the application’s static HTML, CSS and javascript. This is loaded in the browser.&lt;/p&gt;

&lt;p&gt;Thereafter, when your users interact with your application (clicking buttons etc) the javascript, running in the browser, can update the UI there and then (manipulating the DOM directly).&lt;/p&gt;

&lt;p&gt;When the time comes to retrieve data from a backend, much like Blazor WebAssembly, you can make AJAX requests to your server, retrieve data as JSON then update the DOM to render this data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vRfdTh23--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-25-where-to-start/2019-11-11-16-22-53.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vRfdTh23--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-25-where-to-start/2019-11-11-16-22-53.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Common ground
&lt;/h2&gt;

&lt;p&gt;It’s tempting to look at these options and focus in on the differences, but it’s worth thinking about the common ground…&lt;/p&gt;

&lt;p&gt;… they’re all meant for presentation, not business logic.&lt;/p&gt;

&lt;p&gt;MVC, Razor Pages, Blazor and front-end frameworks such as React, Angular and Vue are all intended to help you build your user interface.&lt;/p&gt;

&lt;p&gt;Their role is to render stuff in the browser, and handle “events” such as users clicking buttons, navigating to pages etc.&lt;/p&gt;

&lt;p&gt;If you keep all your actual business logic elsewhere, then we’re talking about a relatively thin layer at the outer edges of your application; that bit where the users actually get to see and click things.&lt;/p&gt;

&lt;p&gt;This is very good news! If you can build your business logic/data retrieval outside of this presentation code you’ll find it much easier to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build your user interface in the first place&lt;/li&gt;
&lt;li&gt;Consider changing UI framework at a later date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And remember, whichever option you choose, you’re always free to change later.&lt;/p&gt;

&lt;p&gt;The fundamental building blocks of all ASP.NET applications are the same (you’ll still be wiring up dependencies in startup.cs, adding DBContexts if you want to use EF Core etc.)&lt;/p&gt;

&lt;p&gt;So choose freely, and remember you get to take everything you’ve learned with you (when you inevitably switch gears in 6 months time!)&lt;/p&gt;

</description>
    </item>
    <item>
      <title>There's a buzz about Blazor</title>
      <dc:creator>Jon Hilton</dc:creator>
      <pubDate>Tue, 15 Oct 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/jonhilt/there-s-a-buzz-about-blazor-112l</link>
      <guid>https://dev.to/jonhilt/there-s-a-buzz-about-blazor-112l</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_Zh6XThX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-14-blazor-buzz/2019-10-15-21-32-54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_Zh6XThX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-10-14-blazor-buzz/2019-10-15-21-32-54.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Blazor has landed (albeit only officially supported in “Server” mode for now) and with it comes renewed optimism that javascript isn’t going to be the only front end game in town for the rest of eternity.&lt;/p&gt;

&lt;p&gt;But can it, will it, should it ever replace Javascript?&lt;/p&gt;

&lt;p&gt;If you’re currently committed to building Web APIs and applications using Vue/Angular/React are you destined to chuck everything in the bin and start all over again from zero?&lt;/p&gt;

&lt;p&gt;Honestly? Probably not.&lt;/p&gt;

&lt;p&gt;But, having seen the enthusiasm for Blazor at recent conferences and “out there” (the Internet, not aliens), I’m increasingly of the opinion that Blazor is a very good thing;&lt;/p&gt;

&lt;p&gt;Here are three reasons why.&lt;/p&gt;

&lt;h2&gt;
  
  
  Alternatives are important
&lt;/h2&gt;

&lt;p&gt;It’s tempting to assume that everyone has got over their objections to JS, embraced the ecosystem in its entirety and are now happily spinning round on their JS framework treadmill, churning out PWAs and SPAs to their heart’s content.&lt;/p&gt;

&lt;p&gt;But, as one person succinctly outlined on /r/dotnet…&lt;/p&gt;

&lt;p&gt;“I hate everything about javascript”&lt;/p&gt;

&lt;p&gt;Who knows how this person really feels… but it’s fair to assume that some people have not jumped on the JS bandwagon and aren’t exactly happy about the prospect of doing so in the near future.&lt;/p&gt;

&lt;p&gt;If you know C# and you’re comfortable operating within the .NET ecosystem, having a JS alternative which enables you to be productive, spin up “modern” web applications which are performant, using the tools you already know and love, sounds like a pretty good option to have up your sleeve.&lt;/p&gt;

&lt;h2&gt;
  
  
  Web Assembly isn’t just Microsoft
&lt;/h2&gt;

&lt;p&gt;You’ve probably read about the two “modes” which Blazor can run in.&lt;/p&gt;

&lt;p&gt;Blazor Server, available now, does all the heavy lifting on the server, transmitting a small amount of data up to the browser to tell it what to render in response to things happening within your application (button clicks etc.)&lt;/p&gt;

&lt;p&gt;But Blazor Server is just the start. When Blazor WebAssembly drops next year, you’ll be able to deploy actual .NET DLLs to the browser.&lt;/p&gt;

&lt;p&gt;Those DLLS will run on a version of the .NET runtime (in the browser) making it a fully-fledged SPA which happens to be written using C#.&lt;/p&gt;

&lt;p&gt;This is enabled thanks to WebAssembly which is built into all modern browsers.&lt;/p&gt;

&lt;p&gt;WebAssembly opens up the browser to run languages other then JS, and you can be sure Microsoft aren’t the only company exploring what this means and how they can best make use of it.&lt;/p&gt;

&lt;p&gt;Chances are we’re going to see the browser move into areas it previously couldn’t, running more diverse applications as the technology matures and improves.&lt;/p&gt;

&lt;p&gt;JS is still a big part of this picture, with WebAssembly able to call into and out of the JS context, but the options will be there to bring the tools and languages you already know to the party.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shared models between browser and server is a BIG deal
&lt;/h2&gt;

&lt;p&gt;If there’s one pain point which springs up again and again with full stack development it’s the problem of multiple versions of the same model.&lt;/p&gt;

&lt;p&gt;With a typical JS based application you’re likely to end up with one version of your Model on the backend (strongly typed, in C# land) and then a completely separate representation of it in javascript (possibly typed if you’re using Typescript).&lt;/p&gt;

&lt;p&gt;Keeping these in sync is a royal pain in the ass. It’s really only a matter of time before something changes on the back end causing a breaking change in the front end.&lt;/p&gt;

&lt;p&gt;Code generation partially solves this problem, or at least removes the manual process otherwise required to keep the two in sync but still leaves you with two versions of the same model.&lt;/p&gt;

&lt;p&gt;Blazor removes the problem entirely.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;@inject&lt;/span&gt; &lt;span class="n"&gt;HttpClient&lt;/span&gt; &lt;span class="n"&gt;_httpClient&lt;/span&gt;

&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;People&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h3&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;span class="nf"&gt;@foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;people&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;Hello&lt;/span&gt; &lt;span class="n"&gt;@person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="n"&gt;h1&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;@code&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;people&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="k"&gt;override&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;OnInitializedAsync&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;LoadPeople&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt; &lt;span class="nf"&gt;LoadPeople&lt;/span&gt;&lt;span class="p"&gt;(){&lt;/span&gt;
        &lt;span class="n"&gt;people&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;_httpClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetJsonAsync&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"http://yourapi.com/people"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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



&lt;p&gt;This is an example of Blazor Client (Web Assembly) using a model &lt;code&gt;Person&lt;/code&gt; which is retrieved via an HTTP call to an API.&lt;/p&gt;

&lt;p&gt;Just the ability to deserialise the API response into the &lt;code&gt;Person&lt;/code&gt; model removes any realistic chance of breaking this application simply by making changes to its models.&lt;/p&gt;

&lt;p&gt;(you also get intellisense, which is nice).&lt;/p&gt;

</description>
      <category>blazor</category>
    </item>
    <item>
      <title>Starting out with the ASP.NET Core React template (part 3  - Separating out the frontend)</title>
      <dc:creator>Jon Hilton</dc:creator>
      <pubDate>Wed, 18 Sep 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/jonhilt/starting-out-with-the-asp-net-core-react-template-part-3-separating-out-the-frontend-4c12</link>
      <guid>https://dev.to/jonhilt/starting-out-with-the-asp-net-core-react-template-part-3-separating-out-the-frontend-4c12</guid>
      <description>&lt;p&gt;So now we &lt;a href="https://jonhilton.net/understanding-the-asp-net-react-template"&gt;know our way round the front end part&lt;/a&gt; of a new React + Web API project, and the &lt;a href="https://jonhilton.net/understanding-the-asp-net-react-template-web-api"&gt;Web API part&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;But we left the last post on a bit of a cliffhanger.&lt;/p&gt;

&lt;p&gt;We saw how you can choose to launch the React part of the application separately (running on its own port and not tied in with rebuilds of your C# API).&lt;/p&gt;

&lt;p&gt;But, if you try this, launch the application and try to access the “Weather” page, you’ll just see the Loading… indicator and no actual data.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8gnEk_he--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-9-18-dotnet-react-template-separate-backend/2019-09-18-21-29-37.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8gnEk_he--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-9-18-dotnet-react-template-separate-backend/2019-09-18-21-29-37.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Broken URLs
&lt;/h2&gt;

&lt;p&gt;So what’s going on?&lt;/p&gt;

&lt;p&gt;Well, now the React frontend is running on &lt;code&gt;localhost:3000&lt;/code&gt;, it’s phsyically separated from your ASP.NET Core Web API.&lt;/p&gt;

&lt;p&gt;So, the code in &lt;code&gt;FetchData.js&lt;/code&gt; is broken…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;api/SampleData/WeatherForecasts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;forecasts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Fetch is going to assume:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;api/SampleData/WeatherForecasts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;is located at:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;http://localhost:3000/api/SampleData/WeatherForecasts&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;which is, of course, wrong.&lt;/p&gt;

&lt;p&gt;What we actually want to do is hit our API server running on another port (40512 in my case; check &lt;code&gt;Properties/launchSettings.json&lt;/code&gt; to discover yours).&lt;/p&gt;

&lt;p&gt;To fix this we could just manually include the correct address in the &lt;code&gt;fetch&lt;/code&gt; call…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;http://localhost:40512/api/SampleData/WeatherForecasts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;forecasts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But we could be making a lot of these network calls and it’s not ideal to have to include that first part of the URL in every case (not least because we might change it at some point during development, and definitely when we go live).&lt;/p&gt;

&lt;p&gt;A better way is to define that URL once and use it everywhere; something we can do quite easily using that &lt;code&gt;.env&lt;/code&gt; file we added last time.&lt;/p&gt;

&lt;p&gt;Currently it looks like this…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BROWSER=none
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But we can add anything we like to it.&lt;/p&gt;

&lt;p&gt;Let’s add our API URL…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BROWSER=none
REACT_APP_API_URL=http://localhost:40512
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To be able to retrieve this value in our React (javascript) code it needs to be prefixed with &lt;code&gt;REACT_APP&lt;/code&gt;. Now we can retrieve this code whenever we need it like so…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;process.env.REACT_APP_API_URL
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;So, a little string interpolation later and we end up with this…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;REACT_APP_API_URL&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/api/SampleData/WeatherForecasts`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;json&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setState&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;forecasts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;loading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Notice the “not quite apostrophe” in there, the backtick at the beginning and end of the url string?&lt;/p&gt;

&lt;p&gt;That allows us to use javascript’s template literals to interpolate expressions in your strings.&lt;/p&gt;

&lt;p&gt;So in this case we’ll get the value of &lt;code&gt;REACT_APP_API_URL&lt;/code&gt; pre-pended to the rest of our string.&lt;/p&gt;

&lt;h2&gt;
  
  
  Changing the URL in production
&lt;/h2&gt;

&lt;p&gt;So far so good but we probably don’t want to use &lt;code&gt;localhost&lt;/code&gt; in production. To use different settings in different environments we can define more than one .env file.&lt;/p&gt;

&lt;p&gt;So in this case, if we define an &lt;code&gt;.env.development&lt;/code&gt; file and put our &lt;code&gt;localhost&lt;/code&gt; URL in there, we can put the actual, production, API address in &lt;code&gt;.env&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;That way we should end up with the correct API urls for both development and prod.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;.env&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REACT_APP_API_URL=https://API.YourDomainHere.io
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;.env.development&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;REACT_APP_API_URL=http://localhost:40512
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Watch out for CORS
&lt;/h2&gt;

&lt;p&gt;The final thing you’ll probably run into when you run your app in production is CORS.&lt;/p&gt;

&lt;p&gt;As soon as you have your frontend and API applications running on different URLs, CORS is likely to raise its head and demand your attention!&lt;/p&gt;

&lt;p&gt;If you see an error indicating that a Cross-Origin request was blocked, chances are you’ve run into CORS.&lt;/p&gt;

&lt;p&gt;CORS exists to stop random code running in the browser from making requests to your API, but it has a nasty habit of cropping up when you try and access your API from your own applications as well.&lt;/p&gt;

&lt;p&gt;Happily, you can easily configure ASP.NET Core with a CORS policy which allows your application through to your API,&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://jonhilton.net/cross-origin-request-blocked/"&gt;this article for more details on CORS&lt;/a&gt; and my handy &lt;a href="https://corsdot.net/"&gt;CORS code generator&lt;/a&gt; to get the code you need to fix the problem.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Starting out with the ASP.NET Core React template (part 2  - Web API)</title>
      <dc:creator>Jon Hilton</dc:creator>
      <pubDate>Fri, 06 Sep 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/jonhilt/starting-out-with-the-asp-net-core-react-template-part-2-web-api-3olm</link>
      <guid>https://dev.to/jonhilt/starting-out-with-the-asp-net-core-react-template-part-2-web-api-3olm</guid>
      <description>&lt;p&gt;So now we &lt;a href="https://jonhilton.net/understanding-the-asp-net-react-template"&gt;know our way round the front end part&lt;/a&gt; of a new React + Web API project, what about the Web API part?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iuDF6ew---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-7-18-dotnet-react-template-backend/2019-09-04-07-29-02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iuDF6ew---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-7-18-dotnet-react-template-backend/2019-09-04-07-29-02.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Everything else in the new project (apart from the ClientApp folder) is there to make your Web API work.&lt;/p&gt;

&lt;p&gt;First up we have the &lt;strong&gt;Controllers&lt;/strong&gt; folder.&lt;/p&gt;

&lt;h2&gt;
  
  
  API controllers for your data
&lt;/h2&gt;

&lt;p&gt;In the controllers folder you’ll find an example controller which returns some hard-coded data for your application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"api/[controller]"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SampleDataController&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Controller&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// other code omitted&lt;/span&gt;

    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nf"&gt;HttpGet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"[action]"&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;WeatherForecast&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;WeatherForecasts&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;rng&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;Random&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Enumerable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;5&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;WeatherForecast&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;DateFormatted&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;AddDays&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;ToString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"d"&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;TemperatureC&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;(-&lt;/span&gt;&lt;span class="m"&gt;20&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;55&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="n"&gt;Summary&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Summaries&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;rng&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Next&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Summaries&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Length&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;// other code omitted  &lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;At the top we have a &lt;code&gt;Route&lt;/code&gt; attribute which means any requests to our application &lt;code&gt;/api/SampleData&lt;/code&gt; will be routed here.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;WeatherForecasts&lt;/code&gt; method has its own &lt;code&gt;HttpGet("[action]")&lt;/code&gt; attribute.&lt;/p&gt;

&lt;p&gt;This tells ASP.NET Core’s routing engine to take any requests to &lt;code&gt;/api/sampledata/WeatherForecasts&lt;/code&gt; and forward them to this method (our controller action).&lt;/p&gt;

&lt;p&gt;The rest of the code in this method (and more code in the controller which I’ve omitted for brevity) simply generates some random “weather” data and returns it as an IEnumerable of &lt;code&gt;WeatherForecast&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The shape of the returned data is defined by the &lt;code&gt;WeatherForecast&lt;/code&gt; type which looks like this…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;WeatherForecast&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;DateFormatted&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;TemperatureC&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Summary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;TemperatureF&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;get&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;32&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TemperatureC&lt;/span&gt; &lt;span class="p"&gt;/&lt;/span&gt; &lt;span class="m"&gt;0.5556&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Testing your work
&lt;/h2&gt;

&lt;p&gt;To test a simple GET like this you can launch your application and click through the various screens in your front end app, or you can take a more direct approach and make HTTP requests direct to your API.&lt;/p&gt;

&lt;p&gt;Start by launching your application.&lt;/p&gt;

&lt;p&gt;If this is the first time you’ve launched you may run into a warning message about a “Potential Security Risk Ahead”; this is because ASP.NET is attempting to run using HTTPS but uses a special “self-signed” development certificate to make it work.&lt;/p&gt;

&lt;p&gt;You wouldn’t want to use that certificate for deployment to production but it’s fine to accept this certificate and continue on your local machine. Here’s what the warning looks like in Firefox.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nmbYQFYA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-7-18-dotnet-react-template-backend/2019-09-04-07-55-30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nmbYQFYA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-7-18-dotnet-react-template-backend/2019-09-04-07-55-30.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once it’s up and runnning, you can test that GET action by simply entering the URL in the browser…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e4uEX9nD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-7-18-dotnet-react-template-backend/2019-09-04-08-00-47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e4uEX9nD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-7-18-dotnet-react-template-backend/2019-09-04-08-00-47.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively you can use other tools to test your API.&lt;/p&gt;

&lt;p&gt;Postman and Insomnia are the two major contenders for this job, with my personal favourite being Insomnia.&lt;/p&gt;

&lt;p&gt;To test your API using Insomnia you need to &lt;a href="https://insomnia.rest/"&gt;download and install it&lt;/a&gt;, then take note of the address your application is running on, and enter it into the URL box at the top of the screen.&lt;/p&gt;

&lt;p&gt;Ensure the request type is &lt;code&gt;GET&lt;/code&gt;, hit &lt;code&gt;Send&lt;/code&gt; and you should see your lovely random weather data returned.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FHI3JToC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-7-18-dotnet-react-template-backend/2019-09-04-07-56-29.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FHI3JToC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-7-18-dotnet-react-template-backend/2019-09-04-07-56-29.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Startup.cs
&lt;/h2&gt;

&lt;p&gt;The other file of note in the backend part of the project is &lt;code&gt;startup.cs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In ASP.NET Core this is where you’ll find yourself configuring your application.&lt;/p&gt;

&lt;p&gt;Take a look and you’ll see various calls to tell ASP.NET how it should operate.&lt;/p&gt;

&lt;p&gt;For example, the following code tells ASP.NET Core to show a “developer friendly” error message if we’re running in development mode (on a development machine)…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsDevelopment&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseDeveloperExceptionPage&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Most of this file is bog standard ASP.NET Core but there are a few React/SPA specific calls.&lt;/p&gt;

&lt;p&gt;Most notably you’ll see a call to &lt;code&gt;UseSpaStaticFiles&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When you run your application in production your React code will be compiled and minified into static &lt;code&gt;.html&lt;/code&gt; and &lt;code&gt;.js&lt;/code&gt; files in &lt;code&gt;ClientApp/build&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;UseSpaStaticFiles&lt;/code&gt; and the corresponding call to &lt;code&gt;AddSpaStaticFiles&lt;/code&gt; ensure these compiled and minified files will be served to the browser when a user visits your application.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;UseSpa&lt;/code&gt; similarly ensures that the default starting page for your React application is served up when requests are made to the application.&lt;/p&gt;

&lt;p&gt;This code…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;IsDevelopment&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;spa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;UseReactDevelopmentServer&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;npmScript&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;… makes sure that your React application is served using the React Development server when running in Development mode (on your machine).&lt;/p&gt;

&lt;p&gt;This gives you more detailed output in the console of the browser and also handles things like auto-refreshing the browser when you make changes to your application.&lt;/p&gt;

&lt;h2&gt;
  
  
  Launch and/or publish your application
&lt;/h2&gt;

&lt;p&gt;It’s worth knowing what’s going on when you launch or publish your application.&lt;/p&gt;

&lt;p&gt;If you take a gander at your application’s &lt;code&gt;.csproj&lt;/code&gt; file you’ll notice some calls to &lt;code&gt;npm&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;Target&lt;/span&gt; &lt;span class="na"&gt;Name=&lt;/span&gt;&lt;span class="s"&gt;"PublishRunWebpack"&lt;/span&gt; &lt;span class="na"&gt;AfterTargets=&lt;/span&gt;&lt;span class="s"&gt;"ComputeFilesToPublish"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="c"&gt;&amp;lt;!-- As part of publishing, ensure the JS resources are freshly built in production mode --&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Exec&lt;/span&gt; &lt;span class="na"&gt;WorkingDirectory=&lt;/span&gt;&lt;span class="s"&gt;"$(SpaRoot)"&lt;/span&gt; &lt;span class="na"&gt;Command=&lt;/span&gt;&lt;span class="s"&gt;"npm install"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class="nt"&gt;&amp;lt;Exec&lt;/span&gt; &lt;span class="na"&gt;WorkingDirectory=&lt;/span&gt;&lt;span class="s"&gt;"$(SpaRoot)"&lt;/span&gt; &lt;span class="na"&gt;Command=&lt;/span&gt;&lt;span class="s"&gt;"npm run build"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;

        &lt;span class="c"&gt;&amp;lt;!-- rest of code omitted for brevity --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/Target&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;When you publish your application these &lt;code&gt;npm&lt;/code&gt; calls ensure any front-end dependencies are downloaded and that your application is built (compiled and minified) ready to be served in production.&lt;/p&gt;

&lt;p&gt;To run your project locally you can just hit CTRL+F5 (in VS) and both parts of the application (front-end and back-end) will be launched together, running at the same web address.&lt;/p&gt;

&lt;p&gt;You can control which port is used by modifying the &lt;code&gt;launchSettings.json&lt;/code&gt; file in the &lt;code&gt;Properties&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;So in this example, if you launched this application using IIS Express it would run on port 40512 (http) or 44360 (https).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"iisSettings"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"windowsAuthentication"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"anonymousAuthentication"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"iisExpress"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"applicationUrl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://localhost:40512"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"sslPort"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;44360&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Launching the React application on its own URL
&lt;/h2&gt;

&lt;p&gt;One downside to running both the React and ASP.NET Core parts of your application together is that any changes to your C# code will trigger a recompile and restart of your application, rendering your React front-end unresponsive for a few seconds.&lt;/p&gt;

&lt;p&gt;The ASP.NET Core build will also take longer because it also has to rebuild the React part of the application, even if you haven’t changed it.&lt;/p&gt;

&lt;p&gt;To work around this you can choose to launch the React part of the application separately, on its own port.&lt;/p&gt;

&lt;p&gt;To do so, add a &lt;code&gt;.env&lt;/code&gt; file to the &lt;code&gt;ClientApp&lt;/code&gt; directory and add this setting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;BROWSER=none
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now you’ll need to launch the React application manually (it won’t launch when you launch the .net application):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ClientApp
npm start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;By default your React app will launch on port 3000.&lt;/p&gt;

&lt;p&gt;Now you need to alert ASP.NET Core to this fact by making a small change to &lt;code&gt;startup.cs&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Replace &lt;code&gt;spa.UseReactDevelopmentServer&lt;/code&gt; with this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spa.UseProxyToSpaDevelopmentServer("http://localhost:3000");
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now when you build and launch your ASP.NET Core app it won’t launch its own React server or restart the one you’ve manually started.&lt;/p&gt;

&lt;p&gt;You’ll find your application running at &lt;code&gt;http://localhost:3000&lt;/code&gt; whilst your ASP.NET Core API continues to run on the port specified in &lt;code&gt;launchSettings.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There are a few gotchas to watch out for if you go down this route: specifically you might find your network requests to the API start failing; my next post will explain why (and how to fix it).&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Starting out with the ASP.NET Core React template</title>
      <dc:creator>Jon Hilton</dc:creator>
      <pubDate>Wed, 03 Jul 2019 00:00:00 +0000</pubDate>
      <link>https://dev.to/jonhilt/starting-out-with-the-asp-net-core-react-template-41dk</link>
      <guid>https://dev.to/jonhilt/starting-out-with-the-asp-net-core-react-template-41dk</guid>
      <description>&lt;p&gt;Agghhh, what’s with all those files when you spin up a new ASP.NET Core and React.js project?!&lt;/p&gt;

&lt;p&gt;The “out of the box” experience if you’re new to either React or ASP.NET Core (or both) can be pretty overwhelming; it’s hard to know where to start.&lt;/p&gt;

&lt;p&gt;So let’s break it down and see what we’ve got.&lt;/p&gt;

&lt;p&gt;First up it’s fairly straightforward to spin up a new project which gives you both React and ASP.NET Core …&lt;/p&gt;

&lt;p&gt;Using the dotnet CLI…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;dotnet new react
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Or Visual Studio/Rider etc.&lt;/p&gt;

&lt;p&gt;Either way you’ll end up with something which looks like this…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vTFtjeJm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-6-26-dotnet-react-template/2019-06-26-21-51-49.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vTFtjeJm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-6-26-dotnet-react-template/2019-06-26-21-51-49.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now at first glance there may seem to be a lot going on here (especially when you start drilling into the various folders) so let’s break it down.&lt;/p&gt;

&lt;p&gt;The project is best considered as two entirely separate entities which happen to be co-located in the same place.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A React application (using “Create React app”)&lt;/li&gt;
&lt;li&gt;An ASP.NET Core Web API backend&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  React front end
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;ClientApp&lt;/code&gt; houses the frontend part of your new application.&lt;/p&gt;

&lt;p&gt;So long as you’re using version 2.1 or higher of the .NET SDK you’ll find this part of the application is a standard React application created using something called “Create React App”.&lt;/p&gt;

&lt;p&gt;The only real difference between this and a CRA app is that the .NET team have also provided some example React components to help get you started.&lt;/p&gt;

&lt;p&gt;When you run the application &lt;code&gt;ClientApp/public/index.html&lt;/code&gt; will be served to your browser.&lt;/p&gt;

&lt;p&gt;In there you’ll see a div which looks like this…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div id="root"&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This element is all important as React will render your application into this div.&lt;/p&gt;

&lt;p&gt;Take a look at &lt;code&gt;ClientApp/src&lt;/code&gt; and you’ll see some .js files and a components folder.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;index.js&lt;/code&gt; you’ll see the very “top” of your application; this is where it all starts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bootstrap/dist/css/bootstrap.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;ReactDOM&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;BrowserRouter&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-router-dom&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./App&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;registerServiceWorker&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./registerServiceWorker&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;baseUrl&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementsByTagName&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;base&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;href&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;rootElement&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;root&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;ReactDOM&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;BrowserRouter&lt;/span&gt; &lt;span class="nx"&gt;basename&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;baseUrl&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/BrowserRouter&amp;gt;&lt;/span&gt;&lt;span class="err"&gt;,
&lt;/span&gt;  &lt;span class="nx"&gt;rootElement&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;registerServiceWorker&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The first few lines bring in various modules from other js files and node modules you need to run the app.&lt;/p&gt;

&lt;p&gt;Then a variable is declared which points to that div we noticed earlier in &lt;code&gt;index.html&lt;/code&gt; (with id &lt;code&gt;root&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ReactDOM&lt;/code&gt; is called to render your application which consists of a &lt;code&gt;BrowserRouter&lt;/code&gt; and &lt;code&gt;App&lt;/code&gt; components into this &lt;code&gt;root&lt;/code&gt; div.&lt;/p&gt;

&lt;p&gt;So far so good.&lt;/p&gt;

&lt;p&gt;Now if you head into the &lt;code&gt;&amp;lt;App /&amp;gt;&lt;/code&gt; component you’ll see yet more of that funny looking “almost HTML” which points to yet more components…&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nx"&gt;Component&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;displayName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;App&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="nx"&gt;render&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Layout&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="nx"&gt;exact&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/counter&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Counter&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;        &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/fetch-data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;FetchData&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Layout&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;That “almost HTML” is actually “JSX”. It may look like HTML but is actually converted into javascript which React then uses to interact with the DOM in your browser.&lt;/p&gt;

&lt;p&gt;This React component (&lt;code&gt;App&lt;/code&gt;) nests a few &lt;code&gt;Route&lt;/code&gt; components inside a &lt;code&gt;Layout&lt;/code&gt; component.&lt;/p&gt;

&lt;p&gt;Already we’re beginning to see how React apps are built as lots of small components which can be composed together.&lt;/p&gt;

&lt;p&gt;In this case, &lt;code&gt;Layout&lt;/code&gt; takes care of rendering things like a NavBar for the application then these &lt;code&gt;Route&lt;/code&gt; components let you assign paths to specific components.&lt;/p&gt;

&lt;p&gt;So when you run the app in a browser and head over to &lt;code&gt;/fetch-data&lt;/code&gt; the &lt;code&gt;FetchData&lt;/code&gt; component will be rendered but if you head to &lt;code&gt;/Counter&lt;/code&gt; then &lt;code&gt;FetchData&lt;/code&gt; will be omitted from the DOM and you’ll get the &lt;code&gt;Counter&lt;/code&gt; component being shown instead.&lt;/p&gt;

&lt;p&gt;Because the &lt;code&gt;Layout&lt;/code&gt; component is rendered by itself (not using a &lt;code&gt;Route&lt;/code&gt; component) it will remain visible all the time (irrespective of the path you navigate to).&lt;/p&gt;

&lt;h2&gt;
  
  
  Next Steps
&lt;/h2&gt;

&lt;p&gt;The best way to figure out how the template works is to explore further and try to break some things!&lt;/p&gt;

&lt;p&gt;When you run the application (from VS or the CLI) you’ll find the React app launches in your browser.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rzmIGMbI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-6-26-dotnet-react-template/2019-06-26-22-27-48.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rzmIGMbI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://jonhilton.net/img/2019-6-26-dotnet-react-template/2019-06-26-22-27-48.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you click on the links in the NavBar you’ll see how the general Layout (including NavBar) remain the same but the rest of the page updates to show the relevant component(s).&lt;/p&gt;

&lt;p&gt;From here on, any changes you make to the front end part of your application will trigger an update in your browser, so you can quickly change/tweak and generally fiddle with stuff and immediately see the results of your efforts!&lt;/p&gt;

&lt;p&gt;Next time we’ll take a quick tour of the Web API part of the project.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>WTF is an Action Delegate?</title>
      <dc:creator>Jon Hilton</dc:creator>
      <pubDate>Fri, 22 Mar 2019 11:13:26 +0000</pubDate>
      <link>https://dev.to/jonhilt/wtf-is-an-action-delegate-9j6</link>
      <guid>https://dev.to/jonhilt/wtf-is-an-action-delegate-9j6</guid>
      <description>&lt;p&gt;In the last post we &lt;a href="https://dev.to/jonhilt/wtf-is-a-lambda-2dg2"&gt;explored what a lambda is&lt;/a&gt;, and what that weird &lt;code&gt;x=&amp;gt;x&lt;/code&gt; syntax is all about.&lt;/p&gt;

&lt;p&gt;Now we know &lt;em&gt;what&lt;/em&gt; it is, you might be wondering &lt;em&gt;where&lt;/em&gt; can you use them and how might you write your own code so that a lambda can be used.&lt;/p&gt;

&lt;p&gt;The answer is delegates! &lt;/p&gt;

&lt;p&gt;Delegates act as a kind of placeholder for a method.&lt;/p&gt;

&lt;p&gt;Let's take an example.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SaveToDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// save here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"could not save"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This method theoretically saves a person object. If something goes wrong, we catch the exception and log an error message to the console.&lt;/p&gt;

&lt;h2&gt;
  
  
  Plug 'n' Play behaviour
&lt;/h2&gt;

&lt;p&gt;Now imagine we're going to call this &lt;code&gt;SaveToDatabase&lt;/code&gt; method from various places and want to be able to change how we log this message on a case by case basis. &lt;/p&gt;

&lt;p&gt;For example, instead of writing to console, sometimes we might choose to send an email instead.&lt;/p&gt;

&lt;p&gt;One way to tackle this would be to make it possible for &lt;code&gt;SaveToDatabase&lt;/code&gt; to take in a method which does the actual error logging. Then we can choose whether to pass in a method which writes to the console or a method which sends an email.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SaveToDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// save here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;SaveToDatabase&lt;/code&gt; now indicates that it expects to receive a method (&lt;code&gt;onError&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Action&lt;/code&gt; type here defines our &lt;code&gt;onError&lt;/code&gt; argument as a delegate which takes zero arguments and doesn't return anything.&lt;/p&gt;

&lt;p&gt;At this point &lt;code&gt;SaveToDatabase&lt;/code&gt; doesn't know anything about what &lt;code&gt;onError&lt;/code&gt; does, it merely knows its shape (a method with no arguments which returns void) and can "invoke" it whenever it likes, using this syntax...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="nf"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This frees us up to pass in different methods when we call &lt;code&gt;SaveToDatabase&lt;/code&gt;.&lt;/p&gt;

&lt;center&gt;
![](https://jonhilton.net/img/2019-02-07-what-are-action-func-delegates/2019-02-08-12-40-16.png)
&lt;/center&gt;

&lt;p&gt;Like so...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"bob"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nf"&gt;SaveToDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;WriteErrorToConsole&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;WriteErrorToConsole&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not save"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we've created a method which takes no arguments and returns void (fulfilling the requirements for &lt;code&gt;onError&lt;/code&gt;) and passed a reference to it along to &lt;code&gt;SaveToDatabase&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Note we're not invoking &lt;code&gt;WriteErrorToConsole&lt;/code&gt; in the &lt;code&gt;Main&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;At no point do we do this...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="nf"&gt;WriteErrorToConsole&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because that would immediately invoke the method and write a message to the console.&lt;/p&gt;

&lt;p&gt;What we want is to pass that method along to &lt;code&gt;SaveToDatabase&lt;/code&gt; which will invoke the method at a time of its own choosing.&lt;/p&gt;

&lt;p&gt;Remember in the last post we discovered we can take a method like &lt;code&gt;WriteErrorToConsole&lt;/code&gt; and "inline" it using lambdas?&lt;/p&gt;

&lt;p&gt;We can do something very similar here...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"bob"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nf"&gt;SaveToDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Could not save"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can't use &lt;code&gt;x=&amp;gt;x&lt;/code&gt; because &lt;code&gt;onError&lt;/code&gt; doesn't expect any arguments. Instead, we use empty parenthesis which serve the same purpose, but for Actions which take zero arguments.&lt;/p&gt;

&lt;h2&gt;
  
  
  I want to say something else
&lt;/h2&gt;

&lt;p&gt;What if we don't want to write "Could not save" to the console, but provide a more specific message (which varies depending on the actual error)?&lt;/p&gt;

&lt;p&gt;For this we need to make our &lt;code&gt;onError&lt;/code&gt; action accept some kind of error message...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whichever method gets passed in (the one which sends an email, or the one which writes to console) could make use of this message string and do with it as it pleases.&lt;/p&gt;

&lt;p&gt;To make this work we need to tweak our declaration of the &lt;code&gt;onError&lt;/code&gt; Action slightly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SaveToDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// save here&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;onError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we're using &lt;code&gt;Action&amp;lt;string&amp;gt;&lt;/code&gt; which means we're expecting a method which takes a single string argument and returns void.&lt;/p&gt;

&lt;p&gt;Our &lt;code&gt;Main&lt;/code&gt; method can take that argument and use it when writing to the console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Main&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"bob"&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="nf"&gt;SaveToDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$"Could not save, error: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s"&gt;"&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Delegates delegates everywhere
&lt;/h2&gt;

&lt;p&gt;As you've seen, delegates are pretty powerful and can be a great way to use the same function to do slightly different things depending on what delegate you pass in.&lt;/p&gt;

&lt;p&gt;Here we've stuck to &lt;code&gt;Action&lt;/code&gt; delegates but you can also use something called a &lt;code&gt;Func&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;More on that next time.&lt;/p&gt;

</description>
      <category>csharp</category>
    </item>
    <item>
      <title>WTF Is a Lambda?</title>
      <dc:creator>Jon Hilton</dc:creator>
      <pubDate>Thu, 07 Mar 2019 14:01:07 +0000</pubDate>
      <link>https://dev.to/jonhilt/wtf-is-a-lambda-2dg2</link>
      <guid>https://dev.to/jonhilt/wtf-is-a-lambda-2dg2</guid>
      <description>&lt;p&gt;If you're just learning C# you've probably come across something like this and wondered what the weird &lt;code&gt;x=&amp;gt;x&lt;/code&gt; is all about...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="n"&gt;things&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SingleOrDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To understand what's going on, let's explore a specific example.&lt;/p&gt;

&lt;p&gt;Let's say you have a collection of People. &lt;/p&gt;

&lt;p&gt;Here's a class to represent a Person...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Person&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Then somewhere in your application, a list of people like this...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;People&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Bob"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;37&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Brian"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;21&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Amy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Age&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;58&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Three people in a list. Each object in the list is an instance of our&lt;br&gt;
&lt;code&gt;Person&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;Now say you want to find the record for "Amy" and display her age.&lt;/p&gt;

&lt;p&gt;You could do this manually by looping through each person until you find&lt;br&gt;
the relevant one...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Exists&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;People&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Amy"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="k"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"we found Amy!, she's "&lt;/span&gt; &lt;span class="p"&gt;+&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Age&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Result will be the instance of "Person" for Amy and we can write her age to&lt;br&gt;
the console.&lt;/p&gt;

&lt;p&gt;Alternatively, rather than typing out endless loops yourself, you can use&lt;br&gt;
some methods built in to C# lists to save yourself a few keystrokes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Exists&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;amy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;People&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SingleOrDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IsAmy&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Under the covers, this will loop through the "People" list, and for each&lt;br&gt;
one it will call &lt;code&gt;IsAmy&lt;/code&gt; to determine whether this is the person we want.&lt;/p&gt;

&lt;p&gt;What does &lt;code&gt;IsAmy&lt;/code&gt; look like I hear you ask.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="nf"&gt;IsAmy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Amy"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;code&gt;SingleOrDefault&lt;/code&gt; expects a function, which takes a &lt;code&gt;Person&lt;/code&gt; and returns a &lt;code&gt;bool&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In here we can put whatever logic we want.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;IsAmy&lt;/code&gt; returns &lt;code&gt;true&lt;/code&gt;, then we're saying this instance of &lt;code&gt;Person&lt;/code&gt; is the&lt;br&gt;
one we want. If we return &lt;code&gt;false&lt;/code&gt; we're saying it isn't.&lt;/p&gt;

&lt;p&gt;We can "inline" our &lt;code&gt;IsAmy&lt;/code&gt; function (to save declaring it separately) like&lt;br&gt;
so...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Exists&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;amy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;People&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SingleOrDefault&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;Person&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; 
                                        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Amy"&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is exactly the same as the last example, except instead of declaring a&lt;br&gt;
separate function we're declaring it "inline".&lt;/p&gt;

&lt;p&gt;You can see we're still taking in a &lt;code&gt;Person&lt;/code&gt; argument, then returning a&lt;br&gt;
&lt;code&gt;true&lt;/code&gt; or &lt;code&gt;false&lt;/code&gt; (true if "Amy", false if not).&lt;/p&gt;

&lt;p&gt;Finally, to make this more concise, we can simplify to this...&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight csharp"&gt;&lt;code&gt;&lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;Exists&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;amy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;People&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;SingleOrDefault&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;person&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="s"&gt;"Amy"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This is another way of declaring the same thing.&lt;/p&gt;

&lt;p&gt;Here, we are still taking the &lt;code&gt;Person&lt;/code&gt;, applying our condition to it and&lt;br&gt;
returning the result (true or false) but with less keystrokes!&lt;/p&gt;

&lt;p&gt;So the left side of the =&amp;gt; is the argument (&lt;code&gt;Person&lt;/code&gt;), the right side is the&lt;br&gt;
expression which returns a boolean.&lt;/p&gt;

&lt;p&gt;Essentially lambdas are really just syntactic sugar and a shorthand way of&lt;br&gt;
declaring a function.&lt;/p&gt;

&lt;p&gt;You'll see them used a lot with lists/other collections and therefore in&lt;br&gt;
relation to database queries etc.&lt;/p&gt;

</description>
      <category>csharp</category>
    </item>
  </channel>
</rss>
