Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to refresh web page after database update in ASP.NET CORE with Blazor

Tags:

c#

asp.net

blazor

I'm making a small room booking web app and I would like to have the web page refresh on a given interval; ie a given minute or when a change has been done to the database. I found StateHasChanged(); but i don't really know how to implement it (Newbie One Kenobi here!) I tried to put it within the function for adding an appointment to the schedule:

var result = Service.CreateSchedule(nextSchedule);
    if (result)
    {
        StateHasChanged();
        NavigationManager.NavigateTo("/roomzfront/1");
    }

But I probably need something more than this, or in an other place of the code.

like image 940
Nicolas Lewentorp Avatar asked Feb 05 '20 12:02

Nicolas Lewentorp


People also ask

How do you refresh a page in Blazor?

A page is reloaded/refreshed automatically at a specified interval using “NavigationManager” in OnAfterRender() method. Here the NavigateTo(“url”, forceLoad: true) method, is used to force load the browser based on the URI.

How do I refresh the Blazor component without reloading the page when database is updated?

How do I refresh the Blazor component without reloading the page when database is updated? You can refresh the Blazor component using the SignalR concept without reloading the page. When using SignalR, saving the changes in one page notifies the changes made to other clients.

Does hot reload work with Blazor?

Blazor WebAssemblyHot Reload reacts to most changes to method bodies, such as adding, removing, and editing variables, expressions, and statements. Changes to the bodies of lambda expressions and local functions are also supported.

How do I Rerender component Blazor?

To force a component to rerender, use the “StateHasChanged” method in Blazor, to notify that the state has been changed and requires re-rendering.


3 Answers

Actually, you don't need to refresh the page just to get the newer version of the database content.

Instead, all we need to do is to re-fetch the data from your database because the content showing in your browser is bound to the data you have fetched when the page first loaded.

For example, if you have a page List.razor showing your data and you can also create new data lines there. So you might have these codes:

@page "/list"
@inject DbService DbService

<h2>All Data Lines<h2>
<table>
    <thead>
        <tr>
            <th>Title</th>
            <th>Content</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var line in dataLines)
        {
            <tr>
                <td>@line.Title</td>
                <td>@line.Content</td>
            </tr>
        }
    </tbody>
</table>

<h2>Add A New Data Line</h2>
<input type="text" placeholder="Title" @bind="newLine.Title"/>
<input type="text" placeholder="Content" @bind="newLine.Content"/>
<button @onclick="AddNewLine">Add</button>

@code 
{
    List<DataLine> dataLines = new List<DataLine>();
    protected override void OnInitialized()
    {
        dataLines = DbService.GetAllData();
    }

    DataLine newLine = new DataLine();
    void AddNewLine()
    {
        DbService.CreateLine(newLine);
    }
}

To help you understand what it looks like, let's run the code in our mind; this is your browser down below:

 (<-)  (->)  (https://contoso.com/list                           )

All Data Lines

|---------------------|------------------|
|        Title        |      Content     |
|=====================|==================|
|        Data1        |      Content1    |
|---------------------|------------------|
|        Data2        |      Content2    |
|---------------------|------------------|

Add A New Data Line

[          Title          ]
[         Content         ]
(Add)

=================End of Your Browser=================

Now let's type in something in Title and Content and then click Add. Your website now starts to submit the "add" request to your Database. After that, you can't see anything changed in the table above until you refresh. That is because the data currently showing in the table is fetched when the page first loaded. When you refresh the page, it will fetch the data again. However if you don't, the data is outdated but all we need to do is to update (fetch) the data manually when your website has done some changes to the database. Which means you can simply add a line dataLines = DbService.GetAllData(); at the end of function void AddNewLine() like this:

void AddNewLine()
{
    DbService.CreateLine(newLine);
    DbService.GetAllData();
}

Now since the data has been re-fetched, your table now is displaying the newest data of your database.

I hope that helps you and if there is anything wrong, feel free to let me know!

like image 79
Stephen Z. Avatar answered Nov 12 '22 22:11

Stephen Z.


you'll need to go with either SignalR or WebSockets - they're supported out of the box these days - to get your DB update notification, although frankly actually getting notifications from a database can be painful unless it's Firebase or SapphireDb.

You could go for the Notifications API but you'll need to write Javascript Interop to chat with the Service Worker and most sane people turn off notifications by default these days. Or I suppose there's Server Push protocol but that's not universally supported and again, service workers.

Regarding actual change notifications, your best bet is to fire them in the middle tier as a part of a successful Write data operation (unless Firebase or Sapphire, as above) but be aware that if data is coming from any other source than just your WebAPI layer, this won't be accurate.

TL;DR - you picked a really tough one. Sounds trivial, especially to management types, but it absolutely isn't.

like image 45
Rich Bryant Avatar answered Nov 13 '22 00:11

Rich Bryant


// To refresh data on your page simply add the StateHasChanged() opcode.

private async void GetEmployeesFromCache()
    {
        var stopWatch = new Stopwatch();
        stopWatch.Start();

        CacheStatus = "Processing";
        Employees = await _employeeManager.GetEmployeesFromCache();
        CacheStatus = $"Completed in { stopWatch.ElapsedMilliseconds} ms";

        StateHasChanged();
    }
like image 45
Muaadeeb Avatar answered Nov 13 '22 00:11

Muaadeeb