Search code examples
c#asp.net-coreblazorclock.net-8.0

Clock on the razor page in Blazor 8


Clock razor page

<h1>Current</h1>
<div id="clock"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js">
<script>
        function updateClock() {
            var now = moment().format('YYYY-MM-DD HH:mm:ss');
            document.getElementById('clock').innerText = now;
        }

        updateClock();

        setInterval(updateClock, 1000);
</script>

procram.cs : grobal rendering mode setting for SSR

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode();

And installed, moment.js library from Nuget.

But the clock only works after refeshing manually.

I tried

    [Inject]
    private IJSRuntime JSRuntime { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await JSRuntime.InvokeVoidAsync("setInterval");
    }

or

app.MapRazorComponents<App>()
    .AddAdditionalAssemblies();

But nothing changed.

How can I make it work automatically?


Solution

  • Clock on the razor page in Blazor 8 . But nothing changed.

    How can I make it work automatically?

    Well, based on your description and shared code snippet it seems that you are trying to make a clock which would be showing YYYY-MM-DD HH:mm:ss. So I not sure why you are using javascript for that!, we actually don't need scripting.

    In order make a clock, all we need is a OnTimerTick that should update with a interval of second, that's it.

    So, we need a time tick funtion /method that would update the clock in every second, you are done.

    Let's have a look how we could refactor your code without JavaScript. If there's any specific requirement for script that's the another story. But you could do as following:

    @page "/clock"
    @implements IDisposable
    
    <div id="clock"><h1>Clock:@currentDateTime </h1></div>
    
    @code {
        private string currentDateTime = "";
        private System.Timers.Timer timer = new System.Timers.Timer();
    
        protected override async Task OnInitializedAsync()
        {
            /*
                I am updating every second
             */
            timer.Interval = 1000; 
            timer.Elapsed += OnTimerTick;
            timer.Start();
            await UpdateClock();
        }
    
        private async Task UpdateClock()
        {
            currentDateTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
            await InvokeAsync(StateHasChanged);
        }
    
        private void OnTimerTick(object sender, System.Timers.ElapsedEventArgs e)
        {
            InvokeAsync(UpdateClock);
        }
    
        public void Dispose()
        {
            timer.Stop();
            timer.Dispose();
        }
    }
    

    Output:

    enter image description here

    enter image description here

    Note: This is one of the way, but if you want to implement using Javascript, please check your browser console if there is any error. But for this clock I don't think that's mandatory. In addition, please refer to this official document for more sample.