Our Blazor App is running on preview9
.
I am trying to implement a .razor
component that listens to an event from a NotificationService we have written to refresh the view whenever the service is invoked, but I seem to be missing something;
I have my service Interface (reduced for brevity);
public interface INotificationService
{
event Action OnChange;
Task<ServiceResponse<Notification>> AddNotificationAsync(Notification notification);
}
and in my implementation I invoke the OnChange
event (again reduced for brevity);
public async Task<ServiceResponse<Notification>> AddNotificationAsync(Notification notification)
{
/*...*/
StateChanged();
}
Where StateChanged()
is;
public event Action OnChange;
private void StateChanged() => OnChange?.Invoke();
In my Blazor.Client
I resolved INotificationService
in ConfigureServices
as follows;
services.AddScoped<INotificationService, NotificationService>();
I then inject the service into the component I want to subscribe to the OnChange()
event;
@inject INotificationService NotificationService
protected override async Task OnInitializedAsync()
{
NotificationService.OnChange += StateHasChanged;
}
And then in my other razor
page I again inject the same service and call the AddNotificationAsync
method;
@inject INotificationService NotificationService
await NotificationService.AddNotificationAsync(
new Notification {
Level = NotificationLevel.Success,
Text = $"Agreement Type with Id = {agreementType.Id} has been successfully added.".ToString()
});
However, calling t NotificationService.AddNotificationAsync
is not triggering the OnChange
and then the StateHasChanged
of the component, as the component is not refreshing? Any ideas what I am doing wrong here please?
Following Microsoft docs Invoke component methods externally to update state, you should to change:
@inject INotificationService NotificationService
protected override async Task OnInitializedAsync()
{
NotificationService.OnChange += StateHasChanged;
}
By:
@inject INotificationService NotificationService
protected override async Task OnInitializedAsync()
{
NotificationService.OnChange += OnNotify;
}
public async Task OnNotify()
{
await InvokeAsync(() =>
{
StateHasChanged();
});
}
In your code, you are invoking the component's StateHasChanged
method outside of Blazor's SynchronizationContext.
InvokeAsync is used to switch to the correct context and queue a render.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With