3

I have a situation where I have a for loop that creates my html table from my datamodel which gets the data from SQL server express. I would like to know if it is possible to create a auto refresh method where the table data only gets refreshed and not the full page, if not then maybe a method that OnClick button will retrieve the latest data from datamodel and update the table accordingly.

I'm new to blazor and C# so any help would be appreciated, my current page structure currently looks as follows:

@page "/employees"

@using DataLib;

@inject IEmployeeData _db

@if (employees is null)
{
    <p style="color:white;"><em>Loading . . .</em></p>
}
else
{
    <table class="table" id="myTable">
        <thead>
            <tr>
                <th>Entry Date</th>
                <th>Employee</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var employee in employees)
            {
                <tr>
                    <td>@employee.EntryDate</td>
                    <td>@employee.POI</td>
                </tr>
            }
        </tbody>
    </table>
}

@code{
    private List<EmployeeModel> employees;

    protected override async Task OnInitializedAsync()
    {
        employees = await _db.GetEmployee();
    }

}

The above works perfect when I'm loading this page and when I do a manual refresh.

Is there a way that you guys can maybe assist me?

Thanks.

Brakkie101
  • 149
  • 1
  • 2
  • 12
  • 1
    Also, take a look here: https://www.c-sharpcorner.com/blogs/using-ajax-in-asp-net-mvc – LostPhysx Jun 08 '20 at 22:32
  • 3
    If refreshing on a timed schedule is sufficient you can [use a timer](https://wellsb.com/csharp/aspnet/blazor-timer-navigate-programmatically/). That example does a navigation, but you can just refresh your data instead of navigate. If you need to refresh the data immediately when the database is updated then that's more complicated but possible. – Crowcoder Jun 08 '20 at 23:37
  • 1
    @Paedow This question isn't a duplicate of the linked question. Blazor works completely differently to the way suggested in the answer. Please could you re-open this question so I can answer it correctly? – Peter Morris Jun 09 '20 at 08:20
  • 1
    @Paedow Please re-open this, the answer you propose is entirely unrelated to the OP's question. – Pancake Jun 09 '20 at 13:38
  • Sorry, I was not aware that it would be immediately closed. I flagged it as a possible duplicate, that's all. – LostPhysx Jun 09 '20 at 17:40

4 Answers4

3

Not sure this is your aim butt you could try;

@inject IEmployeeData _db

@if (employees is null)
{
    <p style="color:white;"><em>Loading . . .</em></p>
}
else
{
    <table class="table" id="myTable">
        <thead>
            <tr>
                <th>Entry Date</th>
                <th>Employee</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var employee in employees)
            {
                <tr>
                    <td>@employee.EntryDate</td>
                    <td>@employee.POI</td>
                </tr>
            }
        </tbody>
    </table>

    <button @onclick="GetEmployees"> Refresh Employee List</button>
}


@code{
    private List<EmployeeModel> employees;

    protected override async Task OnInitializedAsync()
    {
        GetEmployees()

}

    private async void GetEmployees()
    {
        employees.Clear();

        employees = await _db.GetEmployee();

        StateHasChanged();
    }

Good luck,

Mathias Z
  • 422
  • 5
  • 13
1

You could create a SignalR hub on your server. Inject the hub into your api controllers, use it to signal clients that updates have occurred to the data from the API.

Brian Parker
  • 11,946
  • 2
  • 31
  • 41
1

Mathias Z

I not understand why not this answer is not taken for good, but for me is all that i want, StateHasChanged(); because i still not use JavaScript.

    public MyConstructor()
    {
        _My_collection_.CollectionChanged += Change_EventArgs;
    }

    void Change_EventArgs(object sender, EventArgs e) 
    {  
        StateHasChanged();
    } 
Hunab Ku
  • 11
  • 1
0

If your aim is just to refresh the data at regular interval then you can make use of Javascript Interop that is supported by Blazor. The set-up documentation is available in this link.

Like said by Mathias Z in this solution you would need a button for this to work.

I can see you have been writing both C# code and HTML in same file however I personally prefer keeping them separately. Coming back to the solution you can make use to JavaScript and c# to periodically refresh your displayable content.

Below are the changes you need to make to make it work.

Code-Behind

using Microsoft.JSInterop; // import this library

using this you can invoke JavaScript methods.

[Inject]
private IJSRuntime JSRuntime { get; set; }

OnAfterRenderAsync and OnAfterRender are called after a component has finished rendering. Element and component references are populated at this point. Use this stage to perform additional initialization steps using the rendered content, such as activating third-party JavaScript libraries that operate on the rendered DOM elements.

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    await JSRuntime.InvokeVoidAsync("EmployeeInterop.refreshEmployeeData");
}

// This method will be called on button click.
protected async Task GetEmployees()
{
    employees = await _db.GetEmployee();
}

wwwroot

Within this folder we generally keep our web-resources including js libraries. Here, create a javascript file e.g. EmployeeInterop.js and below code.

(function () {
    window.EmployeeInterop = {
        refreshEmployeeData: () => {
            setInterval(() => { 
                document.getElementById("btnGetEmployeeData").click();
            }, 3000);
        }
    };
})();

The setInterval() method calls a function or evaluates an expression at specified intervals (in milliseconds). You can define your own time of refresh.

_Host.cshtml

Register this script file here.

<script src="EmployeeInterop.js"></script>

EmployeeDetail.razor

<button id="btnGetEmployeeData" @onclick="GetEmployees"> Refresh Employee List</button>

Add this below your table tag. In-case you don't want this button to be visible to the end-user then add a style attribute and set it to display:none.

Suprabhat Biswal
  • 3,033
  • 1
  • 21
  • 29