<?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: Chris Key</title>
    <description>The latest articles on DEV Community by Chris Key (@supachris28).</description>
    <link>https://dev.to/supachris28</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%2F328340%2Fb4a4bc54-f589-4e8b-acee-3c14fb0dd91b.jpeg</url>
      <title>DEV Community: Chris Key</title>
      <link>https://dev.to/supachris28</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/supachris28"/>
    <language>en</language>
    <item>
      <title>Changing the page Title in Blazor (Client-side)</title>
      <dc:creator>Chris Key</dc:creator>
      <pubDate>Sat, 01 Feb 2020 15:50:17 +0000</pubDate>
      <link>https://dev.to/supachris28/changing-the-page-title-in-blazor-client-side-880</link>
      <guid>https://dev.to/supachris28/changing-the-page-title-in-blazor-client-side-880</guid>
      <description>&lt;p&gt;One of the first things I found with Blazor was no ability to set the page title.&lt;/p&gt;

&lt;p&gt;This may come natively in time, but for now here is a simple solution.&lt;/p&gt;

&lt;p&gt;Firstly, we need to define some JavaScript - you can put this directly in your &lt;code&gt;index.html&lt;/code&gt; as a &lt;code&gt;script&lt;/code&gt; or in a JS library file. (Ideally the build pipeline would compile all component JS into a single minified file and attach it to the &lt;code&gt;index.html&lt;/code&gt; automatically. One day.)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;setTitle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Setting title&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&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;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;title&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 simply creates a function in the &lt;code&gt;window&lt;/code&gt; scope that sets the title to whatever is in the input.&lt;/p&gt;

&lt;p&gt;Then we create a &lt;strong&gt;PageTitle.razor&lt;/strong&gt; component to use in other components to manage the page title:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@inject IJSRuntime JSRuntime;
@code {
    private String _title = "";
    [Parameter]
    public String Title {
        get {
            return this._title;
        }
        set {
            this._title = value;
            setTitle();
        }
    }


    protected override void OnInitialized() {
        setTitle();
    }

    private void setTitle() {
        System.Console.WriteLine("Blazor setting Title to {0}", this._title);
        JSRuntime.InvokeAsync&amp;lt;string&amp;gt;("setTitle", new object[] { this._title });
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;We inject the &lt;code&gt;JSRuntime&lt;/code&gt; to allow interop with JavaScript. The &lt;code&gt;Title&lt;/code&gt; property has a simple getter, but the setter is designed to trigger a refresh in the code below.&lt;/p&gt;

&lt;p&gt;To use the component in another (I'm using the &lt;strong&gt;Counter&lt;/strong&gt; example), it is used as normal:&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;PageTitle&lt;/span&gt; &lt;span class="na"&gt;Title=&lt;/span&gt;&lt;span class="s"&gt;"Counter"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;ref=&lt;/span&gt;&lt;span class="s"&gt;"PageTitle"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This will change the page title to &lt;em&gt;Counter&lt;/em&gt; when the component is initialised. I've added a reference so that I can use the code below:&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;PageTitle&lt;/span&gt; &lt;span class="n"&gt;PageTitle&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;int&lt;/span&gt; &lt;span class="n"&gt;currentCount&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&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;IncrementCount&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;currentCount&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="n"&gt;PageTitle&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Title&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Counter: {0}"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;currentCount&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;"Incrementing"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;AlertService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addMessage&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;Alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;currentCount&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="n"&gt;Alerts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Info&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;The reference to &lt;code&gt;PageTitle&lt;/code&gt; is created to allow it to be used and wired up to the component specified above by Blazor's default magic.&lt;/p&gt;

&lt;p&gt;Then after incrementing the counter, we set the &lt;code&gt;Title&lt;/code&gt; to the formatted string. You will remember above that the setter has logic to trigger the refresh when the title is changed.&lt;/p&gt;

&lt;p&gt;(My &lt;a href="https://dev.to/supachris28/building-an-alert-service-in-blazor-4poo"&gt;AlertService&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;This works fine (albeit with a tiny delay, but nothing a user will notice). You will get a build warning:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Pages\Counter.razor(18,9): warning BL0005: Component parameter 'Title' should not be set outside of its component. [C:\code\blazor\first-run\WebApplication1\WebApplication1.csproj]&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This could be eradicated by using a method instead of setter, but I wanted to show this way of doing it.&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>blazor</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Building an alert service in Blazor (Client-side)</title>
      <dc:creator>Chris Key</dc:creator>
      <pubDate>Sat, 01 Feb 2020 15:28:22 +0000</pubDate>
      <link>https://dev.to/supachris28/building-an-alert-service-in-blazor-4poo</link>
      <guid>https://dev.to/supachris28/building-an-alert-service-in-blazor-4poo</guid>
      <description>&lt;p&gt;I've been mostly playing with AngularJS and Angular for the last few years at Packt as a dev manager, but now I'm moving to a new role where they've chosen to build a platform with &lt;a href="https://dotnet.microsoft.com/apps/aspnet/web-apps/blazor"&gt;Blazor&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I'm totally brand new to Blazor, and haven't used .Net since 4.0 came out (original framework, Core didn't exist then). I'm going to write up some of my discoveries as part of this migration to be used as a reference for anyone else starting out.&lt;/p&gt;

&lt;h1&gt;
  
  
  Why an Alert Service?
&lt;/h1&gt;

&lt;p&gt;All the tutorials I've seen so far are fairly static, with minimal interaction between pages and components (hint, pages are components). A UI often needs a way of letting a user know something has happened. It may be directly related to the component they are interacting with, in which case popping up a message is pretty easy, but doing it for every component can mean being repetitive. A background service may need to let a user know something has happened, or a component that is going out of focus. In this case, as a component out of focus can't display anything, nor can a service, we need something else to manage messages.&lt;/p&gt;

&lt;p&gt;My requirements were pretty simple - ability to show at any time, in a range of colours (following Bootstrap) and automatically disappear after some seconds.&lt;/p&gt;

&lt;p&gt;I originally looked at a component in the MainLayout that was accessible down the stack through the use of &lt;code&gt;CascadingValue&lt;/code&gt; but it got messy around the redraw and having events for making messages disappear.&lt;/p&gt;

&lt;h1&gt;
  
  
  The code structure
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;= Shared
  = Interfaces
      IAlert.cs
  = Classes
      Alert.cs
  = Enums
      Alerts.cs
  = Services
      AlertService.cs
  MainLayout.razor
= Components
    AlertComponent.razor
= wwwroot
  = css
      alert-service.css
  index.html
Program.cs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  The Code Files
&lt;/h1&gt;

&lt;p&gt;We have an &lt;code&gt;interface&lt;/code&gt; to define the type for the alerts being passed around, not absolutely necessary but useful for mocking tests later on:&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;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IAlert&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;message&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="n"&gt;Alerts&lt;/span&gt; &lt;span class="n"&gt;alert&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;A &lt;code&gt;class&lt;/code&gt; is then used to actually hold the data. Coming from TypeScript, this is unnecessary as anonymous classes do the job perfectly well.&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;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Alert&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;IAlert&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;Alert&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="nf"&gt;Alert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Alerts&lt;/span&gt; &lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;message&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="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alert&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;message&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="n"&gt;Alerts&lt;/span&gt; &lt;span class="n"&gt;alert&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;The &lt;code&gt;enum&lt;/code&gt; is used to hold all the different types of alert: &lt;code&gt;Primary&lt;/code&gt;, &lt;code&gt;Secondary&lt;/code&gt;, &lt;code&gt;Danger&lt;/code&gt;, &lt;code&gt;Warning&lt;/code&gt;, &lt;code&gt;Info&lt;/code&gt; etc.&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;public&lt;/span&gt; &lt;span class="k"&gt;enum&lt;/span&gt; &lt;span class="n"&gt;Alerts&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;Primary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Secondary&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Danger&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Warning&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Dark&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;Light&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;The &lt;code&gt;AlertService&lt;/code&gt; defines our actual code:&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;using&lt;/span&gt; &lt;span class="nn"&gt;System&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;System.Collections.Generic&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;AlertService&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;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;IAlert&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;messages&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;private&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="k"&gt;event&lt;/span&gt; &lt;span class="n"&gt;Action&lt;/span&gt; &lt;span class="n"&gt;RefreshRequested&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;AlertService&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&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;IAlert&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;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;addMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Alert&lt;/span&gt; &lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alert&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;System&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;"Message count: {0}"&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="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Count&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="n"&gt;RefreshRequested&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="c1"&gt;// pop message off after a delay&lt;/span&gt;
        &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Threading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Timer&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;_&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;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;RemoveAt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="n"&gt;RefreshRequested&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nf"&gt;Invoke&lt;/span&gt;&lt;span class="p"&gt;();&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="m"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Threading&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Timeout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Infinite&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;There is a private property to hold the messages in a list, and a public method to add to the list.&lt;/p&gt;

&lt;p&gt;There is also an event setup for when data changes. Then anything that wants to use the data from the service can be notified when changes occur. This event is referenced twice in the&lt;code&gt;addMessage&lt;/code&gt; method - once when the alert is added to the list, and once when it is removed.&lt;/p&gt;

&lt;p&gt;You can see we have a timer set to 8 seconds to remove the top item in the list. If for some reason the list is empty, this could potentially cause problems - ideally some defences should be added here.&lt;/p&gt;




&lt;p&gt;The &lt;code&gt;AlertComponent&lt;/code&gt; has the physical layout and rendering method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@inject AlertService AlertService

&amp;lt;div class="alert-service"&amp;gt;
    @for (int c = 0 ; c &amp;lt; AlertService.messages.Count ; c++)
    {
        &amp;lt;span class="alert @getAlertClass(AlertService.messages[c])"&amp;gt;@AlertService.messages[c].message&amp;lt;/span&amp;gt;
    }
&amp;lt;/div&amp;gt;

@code {
    protected override void OnInitialized() {
        Console.WriteLine("AlertComponent:Initializied");
        AlertService.RefreshRequested += Refresh;
    }

    private String getAlertClass(IAlert alert) {
        return String.Format("alert-{0}", alert.alert.ToString().ToLower());
    }

    private void Refresh() {
        Console.WriteLine("AlertComponent:refreshing");
        StateHasChanged();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Firstly, we inject the &lt;code&gt;AlertService&lt;/code&gt; into the component. There are changes in the &lt;code&gt;Program.cs&lt;/code&gt; below that make this possible.&lt;/p&gt;

&lt;p&gt;We then have some HTML with a razor iterator to build the messages. This is slightly inefficient as every update will recreate all the DOM elements, rather than adding and removing as necessary. This would be much worse if we had a more complex structure, but as it is, it isn't completely terrible. I did try using a &lt;a href="https://blazorstrap.io/alerts"&gt;BlazorStrap  Alert&lt;/a&gt; but it had issues with reading data out of sync (no idea why yet).&lt;/p&gt;

&lt;p&gt;The code is mostly just helpers. When the component is initialised, the AlertService &lt;code&gt;RefreshRequested&lt;/code&gt; event is subscribed and wired to the &lt;code&gt;Refresh()&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;getAlertClass()&lt;/code&gt; method performs the required manipulation to build the CSS class from the Alert object containing the enum.&lt;/p&gt;




&lt;p&gt;We put our component into &lt;code&gt;MainLayout&lt;/code&gt; with simply:&lt;br&gt;
&lt;/p&gt;

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

&lt;/div&gt;



&lt;p&gt;In &lt;code&gt;alert-service.css&lt;/code&gt; we have some fairly simple CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.alert-service&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;position&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;absolute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;top&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;4rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.alert-service&lt;/span&gt; &lt;span class="nt"&gt;span&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;block&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;line-height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2.2rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;text-align&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;right&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.8rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;margin&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.4em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nc"&gt;.alert&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#fff&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-style&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="m"&gt;4px&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.alert-primary&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#158CBA&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#127ba3&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="nc"&gt;.snip&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, in &lt;code&gt;Program.cs&lt;/code&gt; we have to register our service to make it available to components. We add the following line next to where the App is registered (shown together):&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="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RootComponents&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Services&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddSingleton&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;AlertService&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;Now, we can use the &lt;code&gt;AlertService&lt;/code&gt; in any component.&lt;/p&gt;

&lt;p&gt;For example, I added it to the default &lt;code&gt;Counter&lt;/code&gt; page/component:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@page "/counter"
@inject AlertService AlertService
&amp;lt;PageTitle Title="Counter" @ref="PageTitle" /&amp;gt;

&amp;lt;h1&amp;gt;Counter&amp;lt;/h1&amp;gt;

&amp;lt;p&amp;gt;Current count: @currentCount&amp;lt;/p&amp;gt;

&amp;lt;button class="btn btn-primary" @onclick="IncrementCount"&amp;gt;Click me&amp;lt;/button&amp;gt;

@code {
    private PageTitle PageTitle;
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
        this.PageTitle.Title = String.Format("Counter: {0}", currentCount);
        Console.WriteLine("Incrementing");
        AlertService.addMessage(new Alert(currentCount.ToString(), Alerts.Info));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can see we inject the AlertService at the top, as in the AlertComponent. We can then reference it in the &lt;code&gt;IncrementCount()&lt;/code&gt; method based on the definition in the injection. We add our message, and it shows on screen for 8 secs.&lt;/p&gt;

&lt;p&gt;Future changes for this setup would allow for persistent, manually dismissable messages, and to ensure HTML safety in the messages displayed to ensure no XSS capability.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/supachris28/changing-the-page-title-in-blazor-client-side-880"&gt;PageTitle&lt;/a&gt; is another problem I solved....&lt;/p&gt;

</description>
      <category>dotnet</category>
      <category>blazor</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
