0
votes

My problem may be simple but I have been going round and round trying to understand what the problem is. I have a Blazor page with separate model class (references as LsC for the List<Type> or ls for single when looped in code) that loads the data. But when I click to update that data the page does not refresh. If I add a new entry, that page does load the new entry.

The Blazor page code with the problem is simple:

@if (ls.PrimaryContact)
{
    <div style="cursor: pointer;" class="badge badge-pill badge-success">Primary</div>
}
else
{
    <div style="cursor: pointer;" @onclick="@(() =>MakePrimaryContact(@ls.Id))" class="badge badge-pill badge-info">Make Primary</div>
}

The Code should put a green pill when the result in the primary field is true, or put a regular info pill with the make primary text. The code works correctly when the page is manually (F5) refreshed. But when I click on the Make Primary pill, the database does update, but the page does not. I have to again manually update the page to properly reflect the change.

The function it calls onClick:

private void MakePrimaryContact(int LCId)
{
    LeadsContactsGateway LCGw = new LeadsContactsGateway();
    var wt = LCGw.UpdatePrimary(Lead.Id, LCId);
    LsC = LsCGw.GetByLeadsId(Id);
    StateHasChanged();
    OnInitialized();
}

I added the StateHasChanged() as an additional measure, but yet my page does not fetch the updated recordset with the correct primary contact. It is not until I manually (F5) refresh the web page that the proper update is reflected.

Strangely enough on this same page, I have yet another button that adds a new database entry and that update pops in automatically.

Code for new database entry that does NOT have a problem:

<button class="btn btn-primary btn-sm" @onclick="() => NewLeadContactModal.Open()">+ New 
    <i class="icon icon-people-fill icon-white"></i>
</button>

...

<Modal @ref="@NewLeadContactModal">
<Title>Add New Contact for: @Lead.LeadName</Title>
<Body>
    <ContactAdd LeadsId="@Lead.Id"></ContactAdd>
</Body>
<Footer>
    <button type="button" class="btn btn-secondary" data-dismiss="modal" @onclick="() => ContactModalClickHandler(0)">Close</button>
</Footer>
...
 private void ContactModalClickHandler(int completed)
 {
    if (completed > 0)
    { }
    NewLeadContactModal.Close();
    OnInitialized();

 }

Any suggestions would be appreciated.

3
Never call OnInitialized yourself, it is a lifecycle method that only Blazor should call. I think your problem is that your method doesn't actually update ls or LeadPeter Morris
Thanks @peter. If I don't call OnInitialized, like I do after the modal insert of a record, the page does not refresh. On the modal code I addedd OnInitialized to update the record and it shows; however, when I do the same on this simple record updae, the page does not reflect the change that should bue on the 'ls'.Mariano
@Mariano if OnInitialized does some work you want to re-use elsewhere, move it to a separate method and call that method from both. @peter 's advice is goodQuango
@Quango, Thanks. I will try and have only one method where OnInitialized is called. Peter, thanks I am still trying to put my head around how Blazor works all together and by no means do I disqualify a suggestion.Mariano

3 Answers

0
votes

I guess you are calling databse method on OnInitialized() method

Can you try the same using StateHasChanged() you can find the documentation here

https://docs.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.components.componentbase.statehaschanged

Otherwise only solution is to change the value of the item which you are binding in your UI

0
votes

in your Code :

@if (ls.PrimaryContact)
{
    <div style="cursor: pointer;" class="badge badge-pill badge-success">Primary</div>
}
else
{
    <div style="cursor: pointer;" @onclick="@(() =>MakePrimaryContact(@ls.Id))" class="badge badge-pill badge-info">Make Primary</div>
}

At here you wrote -ls.PrimaryContact- if -ls- is a reference type when you change this not need to refresh page because this blazor is change the page codes

if -ls or ls.PrimaryContact- is not reference type you should create a paramater in your page-component like below;

[Parameter] 
public YourModel YourParam { get; set; }

And then

when you call component

<MyComponent YourParam ="@Data"></MyComponent>

So it will work like this

My sample is include both in below ;

@foreach (var item in AllCourseMaster){
     @if(item.Active){
       <div id="first"></div>
      }
     else
     {
      <div id="second"></div>  
     }
}
<button @onclick="@(e=>CollapseClick(item.Id))"></button>

it works

@code{
   void CollapseClick(int id)
    {
        var changed=AllCourseMaster.FirstOrDefault(x=>x.Id==id);
        changed.Active= !changed.Active;
    }
}
0
votes

I thank you very much for your input for it would have not led me to the answer. As I do further research and learn more from all your answers, I found that the key to this problem is related to not only update the UI and the database, but the the DBSet needs to be refreshed and data repopulated on the recordset. I have added the simple line of LsC = LsCGw.GetByLeadsId(Id); in the function. The full function is as follows:

private async Task MakePrimaryContact(int LCId)
    {
        bool isConfirmed = await js.InvokeAsync<bool>("confirm", "Please confirm you want to make Primary?");
        if (isConfirmed)
        {
            LsCGw.UpdatePrimary(Ls.Id, LCId);
            LsC = LsCGw.GetByLeadsId(Id);
            StateHasChanged();
            OnInitialized();
        }
    }

Some would say I need to remove the OnInitialized(), but when I do it does not work with just the StateHasChanged(). With all as is, it does work. The line added to get the leads back into the recordset is what actually refreshed all the data to have the UI refresh properly.

Thank you again.