Execute blazor header OnInitialized on every page navigation

Viewed 1444

I have a Blazor server-side app. It has a common header for all pages. Inside the header's OnInitialized, it checks whether the user has any new messages. If so, it will blink an icon. This code of course will be executed once when the site loads. However, for each subsequent navigation to different pages, it won't execute again.

Is there a way to re-execute this every time a user navigate to whatever page? I understand I could also use a timer in the background to do this, but wondering if it's doable simply by page navigations?

Thanks!

2 Answers

You have 2 options which should work on Server Side and on client side as well.

  1. According to Blazor docs you can subscribe to LocationChanged event. You can do it anywhere where you can get a reference of NavigationManager.

The following component handles a location changed event by subscribing to NavigationManager.LocationChanged.

  1. You can override OnAfterRenderAsync Blazor method on your MainLayout.razor page. Since this is a shared layout component it will be rendered every time when App navigates. You can even @inject NavigationManager _navigationManager to check which page rendered.

Code example for option 2:

@inject NavigationManager _navigationManager
@code {
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        var url = _navigationManager.Uri;
        //write you code here...
    }
}

Probably option 2 is the best way to use since your code will run on a rendered UI so you have elements to change.

If you server side, why not all InvokeAsync(StateHasChanged) in case a new message is there.

So do in your *.razor code section:

protected override async Task OnInitializedAsync()
{
    MyBackendService.OnUpdate += OnUpdate;
}

private void OnUpdate()
{
    // May be additional code to load the message - if requred
    InvokeAsync(StateHasChanged);        
}

And in the BackendService where the new message arrives or is created:

public event Action OnUpdate;
internal void UpdateView() => OnUpdate?.Invoke();

And now you can call UpdateView() in case there is a new message, like a callback to the view for reloading.

Related