1

In my blazor app for administrating cases, I have a property ClaimedBy on an instance of a class CaseDetails.cs which holds the username of the administrator who has claimed the case.

It is displayed like this on the index page: <p>Claimed by: @caseDetails.ClaimedBy</p>

Now, from a child component, I'm trying to update the value of ClaimedBy like this: caseDetails.ClaimedBy = newUser;

But the name on the index page (the parent component), is not updated automatically. It updates correctly if I make a button on the index page with a method that calls StateHasChanged() like this:

<button @onclick="UpdatePage">update page</button>

@code {
    private void UpdatePage()
    {
        StateHasChanged();
    }
}

I have tried to call StateHasChanged() from my child component, in the same method which sets the new value of the ClaimedBy property, but that doesn't work. StateHasChanged() has to be called from the parent component. How do I get it to update automatically once the new value has been set?

Oskar
  • 41
  • 5
  • 1
    It's better to use EventCallBack parameter to pass a value from the child to the parent component and then call await InvokeAsync(StateHasChanged) – Arani Feb 14 '23 at 05:45
  • 1
    Thanks for reply, but how would I use event callback? – Oskar Feb 14 '23 at 06:05
  • 1
    I implemented your desire code by EventCallBack in the answer, I hope it helps you. – Arani Feb 14 '23 at 06:09

1 Answers1

2

I implemented your code by EventCallBack and it works correctly:

Parent:

@page "/parent"
@using CheckStateHasChanged.Class
@inject CaseDetails caseDetails
<h3>Parent</h3>
<p>Claimed by: @caseDetails.ClaimedBy</p>
<Child caseDetailClaimedBy="UpdatePage"></Child>

@code {

    string claimedByInParent = string.Empty;

    public async Task UpdatePage(string claimedByFromChild)
    {
        claimedByInParent = claimedByFromChild;
    }
}

Child:

@using CheckStateHasChanged.Class
@inject CaseDetails caseDetails
<h3>Child</h3>
<button @onclick="(()=>UpdatePage(caseDetails.ClaimedBy))"></button>

@code {
    [Parameter]
    public EventCallback<string> caseDetailClaimedBy { get; set; }

    public async Task UpdatePage(string claimedBy)
    {
        caseDetails.ClaimedBy = "test";
        await caseDetailClaimedBy.InvokeAsync(claimedBy);
    }
}

CaseDetails.cs

namespace CheckStateHasChanged.Class
{
    public class CaseDetails
    {
        public string ClaimedBy { get; set; } = "admin";
    }
}

For more info about EventCallBack you can refer to Component events and 5-steps-to-implement-event-call-backs-in-blazor

Arani
  • 891
  • 7
  • 18
  • EventCallbacks are one way to do it, but can this be done via data-binding? A lot of things update automagically when a parameter/property is updated. I have, for example, many places where on a parent page, I do like `@if (_myPoco.IsSomeBoolTrue) { update UI }` and all I need to do, is to update theIsSomeBoolTrue, and the UI changes with it. But, I tried the same approach in a Component, where the Parameter is assigned from the Component itself, but in this case, Parent does not update automatically. – Ted Apr 06 '23 at 02:25
  • I think the another way that you can do it is `shared service`. For more info, please refer to this question.https://stackoverflow.com/questions/55775060/blazor-component-refresh-parent-when-model-is-updated-from-child-component – Arani Apr 08 '23 at 05:12