Blazor Timer Navigate Programmatically

In this Blazor tutorial, you will learn how to create a timer. You will also learn how to navigate to pages from your C# code programmatically using NavigationManager.

For the purposes of this tutorial, you will consider a scenario where an event is raised by a timer service in a Blazor application. This event will be handled by some event handler method, and you will navigate to another page in our web app from this event handler instead of by clicking a link.

Create a Blazor Timer Service

To create a service, follow the procedure from the previous tutorial about how to register a C# service in a Blazor app. Within your Blazor project, create a Services folder and add a C# class to it, called BlazorTimer.cs. The BlazorTimer class should include a public SetTimer() method that will be used to start a timer. It should also define an event to be raised once the timer reaches zero.

Consider the following Blazor timer service class:

using System;
using System.Timers;

namespace TimerService.Services
{
    public class BlazorTimer
    {
        private Timer _timer;

        public void SetTimer(double interval)
        {
            _timer = new Timer(interval);
            _timer.Elapsed += NotifyTimerElapsed;
            _timer.Enabled = true;
        }

        public event Action OnElapsed;

        private void NotifyTimerElapsed(Object source, ElapsedEventArgs e)
        {
            OnElapsed?.Invoke();
            _timer.Dispose();
        }
    }
}

This class uses a private Timer field, because there is no need to access the Timer outside of this class. If you do need direct access to the Timer in your use-case, feel free to make the necessary adjustments. The SetTimer() method takes a double argument corresponding to the duration of the timer, in milliseconds. The timer begins when _timer.Enabled is set to true.

Observe that an event handler, NotifyTimerElapsed, has been attached to the Timer.Elapsed event on Line 13. NotifyTimerElapsed() simply invokes the OnElapsed action delegate and disposes of the timer. The OnElapsed delegate, declared on Line 17, will be used to assign and attach a handler method from outside the class.

The C# class is complete, but it must be registered as a service in the web app’s Startup.cs file.

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<Services.BlazorTimer>();
}

Since you don’t need a single instance of this timer service across the entire lifetime of the app, just add it as a transient service instead of a singleton. In a transient service, a new instance will be issued each time one is requested.

Inject Service Into Blazor Page

Recall that to use a service within a component of your application, it must be injected as a dependency. Since the BlazorTimer class is located within the Services directory, your @inject statement will look like the following, where Timer is the name you will reference the service by on the current page.

@inject Services.BlazorTimer Timer

Inject the timer you just created onto the Index page, Index.razor. In the following snippet, I am using a button to start a 5 second timer.

@inject Services.BlazorTimer Timer
@page "/"

<h1>Blazor Timer</h1>

<button @onclick="StartTimer">Start Timer</button>

@code {
    private void StartTimer()
    {
        Timer.SetTimer(5000);
        Timer.OnElapsed += TimerElapsedHandler;
        Console.WriteLine("Timer Started.");
    }

    private void TimerElapsedHandler()
    {
        Console.WriteLine("Timer Elapsed.");
    }
}

The button’s @onclick event is handled by the C# method, StartTimer(). StartTimer() also assigns the TimerElapsedHandler() method to the OnElapsed delegate you created earlier in BlazorTimer.cs. Therefore, this page’s TimerElapsedHandler() will also be invoked when the timer’s Elapsed event is raised.

Once the button is clicked, the timer will begin and “Timer Started.” will be printed to your browser’s JavaScript console. Five seconds later, the timer will elapse, and “Timer Elapsed.” will print to the console.

Navigate to Page Programmatically

Now, suppose you want to navigate to a different page once the timer reaches zero. This could be useful if you were using Blazor to develop a browser-based game, or just a simple countdown timer webapp.

To navigate to a different page programmatically in Blazor, you must inject the NavigationManager service.

@inject NavigationManager NavManager

NavigationManager is a service that is automatically added to your Blazor app’s IServiceCollection by default, so you do not need to register it yourself. It offers a number of member methods, but you will use the NavigateTo() method in this example.

Suppose you have created a page called CountdownComplete.razor with the following content.

@page "/countdowncomplete"
<h3>Time's up!</h3>
<p>You have been redirected to this page because the Blazor timer reached 0.</p>

Notice, this page is accessed from the route /countdowncomplete. Back in your Index.razor page, you could navigate to this page by passing the route to the NavigateTo() method of the NavigationManager service.

private void TimerElapsedHandler()
{
    Console.WriteLine("Timer Elapsed.");
    NavManager.NavigateTo("countdowncomplete");
}

Your complete Index.razor may look like the following:

@inject Services.BlazorTimer Timer
@inject NavigationManager NavManager
@page "/"

<h1>Blazor Timer</h1>

<button @onclick="StartTimer">Start Timer</button>

@code {
    private void StartTimer()
    {
        Timer.SetTimer(5000);
        Timer.OnElapsed += TimerElapsedHandler;
        Console.WriteLine("Timer Started.");
    }

    private void TimerElapsedHandler()
    {
        Console.WriteLine("Timer Elapsed.");
        NavManager.NavigateTo("countdowncomplete");
    }
}

The Bottom Line

In this tutorial, you learned how to create a timer service in Blazor. You also learned how to add an event to the class, and how to attach event handlers to the event. Specifically, you learned about adding an event handler from within the class and from outside the class by using a delegate. As an exercise, try to extend this service in order to display the countdown timer on the current page. This tutorial also taught you a technique for navigating to a new page in your Blazor application from within C# code by using the NavigationManager. This is helpful when you want to take the user to specific page when a particular event is raised instead of when a link is clicked.

The source code for this project is available on GitHub. If you found this tutorial helpful, leave me an encouraging note in the comments. If you have any questions, feel free to ask.


Was this article helpful? Share it with your friends:

Share on email
Share on facebook
Share on twitter
Share on reddit

5 thoughts on “Blazor Timer Navigate Programmatically”

  1. Hi!
    I’m an old VB6 developer who’s returning to programming. I tried asp.net but didn’t care much for it, to be honest I don’t care much for oop either. I’ve been using Xamarin for a while now and thought I give web a go with Blazor.
    What I don’t get is the use of a service here. Since it’s transient why bother registring it as a service, what’s the upside to that instead of just creating an instance with BlazorAppWasm.Services.BlazorTimer timer = new BlazorAppWasm.Services.BlazorTimer();?
    I don’t really get why to put it in a class in the first place, why not just a: using System.Timers; and Timer timer = new Timer(5000); in the razor page and skip the BlazorTimer.cs class all together since it doesn’t contain any extra logic?
    The last question is maybe more of a philosofic nature, since I seldom see use of object orientation when ui centered event-driven logic would work in Blazor and long code blocks could be just split into different methods – but please, persuade me to get over to the ever growing oo camp! 🙂
    A completely different question – since Blazor is somewhat view-centric – where are the components for Blazor, like a Grid you can drag from Toolbox in Visual Studio?

    Reply
    • That’s a pretty wide open when you ask for someone to convince you that OO is the way to go as object oriented design has many documented articles on it’s advantages. You can google and find some that go into great detail. I will say this, one of the biggest advantages we have seen recently is inheritance. We had developers copying old VB code (converted to C#) over and over for our projects since they were similar and then adding specific code unique to that once project. At one point the someone found a bug in the copied code and we had go add the fix to over 50 different programs that used that original code. Then we got smart and create a base class that had all the common code and each program then inherited that base class and got all the functionality for free and then each developer added their specific code that was needed for their project. Now when we find a bug or enhance the base class, all those programs get the changes easily.

      Reply
  2. Hi Bradley,
    I am following your example strictly but I get the error:
    (using the name “tmr” instead “Timer” in your example.)
    @inject Services.BlazorTimer tmr

    crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
    Unhandled exception rendering component: Cannot provide a value for property ‘tmr’ on type ‘TimerX.Client.Pages.Index’. There is no registered service of type ‘TimerX.Client.Services.BlazorTimer’.
    System.InvalidOperationException: Cannot provide a value for property ‘tmr’ on type ‘TimerX.Client.Pages.Index’. There is no registered service of type ‘TimerX.Client.Services.BlazorTimer’.
    at Microsoft.AspNetCore.Components.ComponentFactory+c__DisplayClass5_0.g__Initialize|2 (System.IServiceProvider serviceProvider, Microsoft.AspNetCore.Components.IComponent component) in :0

    Can you help me ?
    Regards,
    Johnny

    Reply
  3. To Adam Berg. Hi Adam. I’m also VB6 programmer. Firtly Blazor don’t have components like grid, also Microsoft leave Visual Studio Designer at all. And Microsoft leave Visual Basic support, jQuery support and all convenient programmer tools. Why? Because development will be slowly, more sophisticated and will be have more price. And this idea full fit to Microsoft point of view – increase price of program development and than increase cost of stock of Microsoft company as software leader company. This is main think you must to understand. More hard programming, more spend time, more efforts induce more cash flow to Microsoft. About you third question, yes, you can place timer exactly in page, and also you can most old way – javascript timer. All this solution as finishing result is equivalent, but solution is this article is most sophisticated and complex, and full fit to Microsoft point of view to increase cost of program.

    Reply
    • You can check my opinion in any freelance site. Any program VB6 and VB.NET developer created for one day and $20, C# developer with modern technology can create for $1000 and one month. As a result of this Microsoft efforts price of Microsoft as whole company increase 10 times and rich 1 billion dollars. There do not search sense of any modern Microsoft solution outside this opinion, this is universal answer for any questions – why Microsof vilified Visual Basic, where is toolbox with components, where is jQuery support, where is designer of Visual Studio and so on.

      Reply

Leave a Comment

Looking for more?

You have visited our site before, and we appreciate you!

If you found the tutorials helpful, enter your email address for more free C# tips and tricks.

Can't get enough C#?

Enter your email address for more free C# tutorials and tips.