Home > OS >  Why isn't Razor/Blazor(WASM) page refreshing after update in both cases sending in two identica
Why isn't Razor/Blazor(WASM) page refreshing after update in both cases sending in two identica

Time:11-05

Trying to shorten things down, one button has this code (takes the first vacant slot and updates the DB as not vacant):

@onclick="@(e => UpdateTimeSlot(@FirstVacantSlot, "Booked", BookerGuid))"

and the other button has this code (user picks a vacant spot):

@onclick="@(e => UpdateTimeSlot(@selectedItem, "RowBooked", BookerGuid))"

Calling after update:

protected override async Task OnParametersSetAsync()
{
    await RefreshDb(); // get list of todays timeslots from DB 
    StateHasChanged(); // well, Blazor magic refresh or whatever
}

FirstVacantSlot is set from a method that picks it from the DB. selectedItem is set when clicking a row in a (MudBlazor) table. Both get filled with the same type of data and send to the method UpdateTimeSlot. Both buttons correctly updates the DB, but the table refreshes ONLY after use of the first button, not after the second button. Why? Also, if I click the second button and then the first button the update no longer works there either.

Things I tried:

  • Debugged to see that the objects have identical values populated. Trying to follow whats happening.
  • StateHasChanged() in every corner of the code.
  • await this.OnParametersSetAsync() (Which makes the first button work)

Add; The UpdateTimeSlot method:

I substituted a call to RefreshDb() with the OnParameterAsync(). Still can't understand why it beahves differently depending on which button I click.

private async Task UpdateTimeSlot(TimeSlotDto vacantSlot, string title, Guid bookerId)
{
    var updateTimeSlot = new TimeSlotDto();
    updateTimeSlot.ID = (Guid)vacantSlot.ID;
    updateTimeSlot.TimeSlotStart = vacantSlot.TimeSlotStart;
    updateTimeSlot.TimeSlotEnd = vacantSlot.TimeSlotEnd;
    updateTimeSlot.IsVacant = false;
    updateTimeSlot.CreatedUTC = vacantSlot.CreatedUTC;
    updateTimeSlot.Title = title;
    updateTimeSlot.UpdatedUTC = DateTime.UtcNow;
    updateTimeSlot.BookerId = bookerId;
    await _http.PutAsJsonAsync($"https://localhost:44315/api/v1/TimeSlot/Update?id={updateTimeSlot.ID}", updateTimeSlot);

    //await this.OnInitializedAsync();

    await this.OnParametersSetAsync();
}

UPDATE The problem has been located to the MudBlazor component Table, which isn't updating correctly after selecting a row in the table itself. Everything else is working as it should; I tried a foreach-loop to iterate through the IENumerable currentTimeSlots, that the MudTable also is dependent on and the foreach-loop updated correctly. So I guess it's a completely different question now.

Update - RefreshDb()

private async Task RefreshDb()
    {
        var roomClient = new RoomClient();

        room = await roomClient.GetRoomByIdAndDateAsync(ThisRoomId, dtToday);

        allTimeSlotsOfToday = room.TimeSlots;
        currentTimeSlots = allTimeSlotsOfToday.GetAllCurrentTimeSlots(dtToday);
        HasItems = currentTimeSlots.Count();
        FirstVacantSlot = allTimeSlotsOfToday.GetFirstVacant(dtToday);
        AnyVacantSlot = allTimeSlotsOfToday.Count(f => f.IsVacant);
    }

CodePudding user response:

A bit of a trick to get the thread released is to add a Task.Delay. You shouldn't need to call OnParametersSetAsync (seems a bit kludgy).

Change your onclicks to something like:

@onclick="@(async () => await UpdateTimeSlotAsync(@FirstVacantSlot, "Booked", BookerGuid))"

Then an async handler:

private async Task UpdateTimeSlotAsync(...)
{
    // update slot code...
    await RefreshDb(); // get list of todays timeslots from DB 
    StateHasChanged(); // well, Blazor magic refresh or whatever
    await Task.Delay(1); // let UI refresh
}

CodePudding user response:

Firstly, never call OnInitialized{Async} or OnParametersSet{Async} manually. They are part of the ComponentBase infrastructure.

Try this:

You're calling await RefreshDb(); which I assume contains the code to do the refresh.

Update OnParametersSetAsync to:

protected override async Task OnParametersSetAsync()
{
    await RefreshDb(); // get list of todays timeslots from DB 
    // StateHasChanged(); not required if RefreshDb is coded correctly.
}

UpdateTimeSlot should look like this:

private async Task UpdateTimeSlot(TimeSlotDto vacantSlot, string title, Guid bookerId)
{
    ....
    await _http.PutAsJsonAsync($"https://localhost:44315/api/v1/TimeSlot/Update?id={updateTimeSlot.ID}", updateTimeSlot);
   await RefreshDb(); 
    // StateHasChanged(); if this fixes the problem then RefreshDb is not coded correctly.
}

You need to ensure RefreshDB is a proper async method that returns a Task that can be awaited, and any sub method calls are also awaited correctly. If a call to StateHasChanged at the end of UpdateTimeSlot fixes the problem then RefreshDb has an await problem.

Update your question with the RefreshDb code if necessary.

  • Related