Search code examples
c#blazormudblazor

how to re-render a MudBlazor MudDataGrid after a database update from a modal form in Blazor


I'm using the MudDataGrid with a data edit function from a modal popup (Blazorise.Modal). Clicking a button on a row retrieves an instance of that data (single record) and puts it into a modal for editing. After editing, clicking the submit button on the modal popup saves the data to the database and closes the modal popup. This works perfectly well but I'm unable to re-render (refresh) the MudDataGrid afterwards so the changes I make dont show up in the MudDataGrid. How Can I refresh the grid ? This is the code I have so far

The data grid setup

<MudDataGrid ServerData="LoadGridData" T="AgencyGridViewModel" @ref="_dataGrid" ReadOnly="true">
    <ToolBarContent>
        <MudText Typo="Typo.h6">Agencies</MudText>
        <MudSpacer />
        <MudTextField @bind-Value="_searchString" Placeholder="Search" Adornment="Adornment.Start" Immediate="true"
                      AdornmentIcon="@Icons.Material.Filled.Search" IconSize="MudBlazor.Size.Medium" Class="mt-0"></MudTextField>
    </ToolBarContent>
    <Columns>
        <PropertyColumn Property="x => x.Id" Hidden />
        <PropertyColumn Property="x => x.AgencyIdentifier" Hidden />
        <PropertyColumn Property="x => x.AgencyName" Title="Agency Name" />
        <PropertyColumn Property="x => x.AgencyAdd1" Title="Address 1" />
        <PropertyColumn Property="x => x.AgencyAdd2" Title="Address 2" />
        <PropertyColumn Property="x => x.AgencyTown_City" Title="Town/City" />
        <PropertyColumn Property="x => x.AgencyPostcode" Title="Postcode" />
        <TemplateColumn  CellClass="d-flex justify-end">
            <CellTemplate>
                <div @onclick:stopPropagation="true" @onclick:preventDefault="true">
                    <MudIconButton Size="@MudBlazor.Size.Small" Icon="@Icons.Material.Rounded.Edit" @onclick="() => EditItem(context.Item!)" />
                </div>
            </CellTemplate>
        </TemplateColumn>
    </Columns>
    <PagerContent>
        <MudDataGridPager T="AgencyGridViewModel" Disabled="false" />
    </PagerContent>
</MudDataGrid>

This loads the data into the grid

private async Task<GridData<AgencyGridViewModel>> LoadGridData(GridState<AgencyGridViewModel> state)
{
    lastGridState = state;
    var result = await AgencyService.GetPagedAsync(new PagedMessageRequest() { Page = state.Page, PageSize = state.PageSize }, this.CancelToken);
    Agencies = Mapper.Map<IEnumerable<AgencyDto>, IEnumerable<AgencyGridViewModel>>(result.Result);
    GridData<AgencyGridViewModel> data = new()
    {
        Items = Agencies.AsQueryable(),
        TotalItems = result.Count
    };
    return data;
}

This activates the modal popup (predefined in the page)

private async Task<Task> EditItem(AgencyGridViewModel item)
{
    var result = await AgencyService.GetAgencyAsync(item.Id, item.AgencyIdentifier, this.CancelToken).ConfigureAwait(true);
    Agency = Mapper.Map<AgencyDto, AgencyViewModel>(result);
    return modalRef.Show();
}

This code is run when the submit button is pressed on the modal popup (there is an edit form in the modal)

private async void OnValidSubmit(EditContext context)
{
    if (context.Validate())
    {
        var agencyDTO = Mapper.Map<AgencyViewModel, AgencyDto>(Agency);
        var request = new UpdateAgencyRequest(agencyDTO);
        await AgencyService.SaveAsync(request, this.CancelToken).ConfigureAwait(false);
        _ = modalRef.Hide();
        await LoadGridData(lastGridState);
        await InvokeAsync(StateHasChanged);
    }
}

This works ok, the data is saved and the modal shuts down, however, the grid never refreshes

From my understanding, this line should re-render the component

await InvokeAsync(StateHasChanged);

It doesn't though, Have I got this wrong ? How can I re-render (refresh) the grid in this case ?


Solution

  • Yes that tells the UI to re-render the component but it does not necessarily fetches the data from the database to update the UI.

    in your method, do a page refresh to get the data from the database after the update.

    public class YourServiceName(NavigationManager navigationManager)
    {
        private readonly NavigationManager _navigationManager = navigationManager;
    
        YourUpdateMethod()
        {
              Your update logic
              _navigationManager.Refresh(true);
        }
    }
    

    Hope that helps