4
votes

Trying to use the solution generated by the latest templates.

  • Having a service whih keeps the list of string.
  • injecting the service in both MainLayout.razor and NavMenu.razor
  • The servie has simple methods viz Add, Remove, Items
  • In the MainLayout, using the OnInitializedAsync() adding some items like following

.

protected override async Task OnInitializedAsync()
    {
        await Task.Run(() =>
        {
            this.svc.Add("string one");
            this.svc.Add("string two");
        });
         await Task.Run(() => StateHasChanged());
    }
  • In the html fragment of NavMenu.razor, i am simple trying to print

    @svc.Items.Count

  • With above code i am not seeing the count getting updated/refreshed, i can have another button handler in MainLayout as well to call the svc.Add method , but count does not get updated.

  • Only when i try to have some btn handler in the navMenu.razor the blazor re-renders itself

<button @onclick="SetCurrentTime"> Time </button>
    <h4>@time</h4>
        
    void SetCurrentTime()
            {
                time = DateTime.Now.ToLongTimeString();
            }

github repo for this problem: (hit AddString and counter should increment) https://github.com/pkaushik23/mycodeshares/tree/master/CheckRefreshBlazor

enter image description here

1
Easy on the Task.Run() stuff. You should probably remove all of that and try again. - Henk Holterman
Thanks @HenkHolterman, as this was a sample code, but in reality i would be getting that from some api call. The await/asyn stuf is not necessary there ? Also, as I have a service in picture some other component would call the Add method on the service and i want my navBar component to show updated list. - Prerak K
client-side you don't have threads so Task.Run() can't be useful, it could only deadlock things. - Henk Holterman
No repro. Go and create a minimal reproducible example and make sure it shows the problem. - Henk Holterman
Thanks, i am still learning. about task, i got confused by this docs.microsoft.com/en-us/aspnet/core/blazor/…. Please can you advise if you know where can i do the MRE. - Prerak K

1 Answers

4
votes

Your NameService should to notify changes. Learn about it on Invoke component methods externally to update state

For your service code, something like:

public class StringService
{
    public event Func<string, Task> Notify;
    public List<string> Names { get; set; } = new List<string>();
    public void Add(string s)
    {
        this.Names.Add(s);
        if (Notify != null)
        {
            await Notify.Invoke(s);
        }            
    }
}

on your components:

protected override void OnInitialized()
{
    this.svc.Notify += OnNotify;
}

public async Task OnNotify(string s)
{
    await InvokeAsync(() =>
    {            
        StateHasChanged();
    });
}