Reputation: 381
I have a blazor component that displays a table of calls associated with an employee. The user can right click the call associated with an employee and change the status of that call. For the right click menu I'm using the Radzen context menu https://blazor.radzen.com/contextmenu
I'm quite new to Blazor and I'm having trouble refreshing the list of calls after the right click action has been completed. I've tried StateHasChanged()
, InvokeAsync(StateHasChanged)
, and I've tried updating the assignedCalls variable thats holding the table/list shown on screen, hoping it would trigger the page to render with the updated details. Nothing has seemed to work. The context menu doesnt seem to have an async
method so I've used Task.Run
to call my async service calls. I dont think this is the issue as this all works fine.
I've ran out of idea to try, any help would be greatly appreciated. The code can be seen below:
@code {
[Parameter]
public string? SelectedCrewMemberId { get; set; }
[Parameter]
public string? SelectedCallId { get; set; }
[Parameter]
public DateTime FromDate { get; set; }
[Parameter]
public DateTime ToDate { get; set; }
List<AssignedCallDto> assignedCalls = new List<AssignedCallDto>();
List<string> selectedAssignedCallIds = new List<string>();
bool loading = false;
protected override async Task OnParametersSetAsync()
{
base.OnParametersSet();
if (loading)
{
return;
}
if (SelectedCrewMemberId is not null)
{
try
{
loading = true;
assignedWork = await actionCallService.GetAssignedCallsByEmployeeId(SelectedCrewMemberId, FromDate, ToDate);
}
finally
{
loading = false;
}
}
}
public async Task UpdateDispatchBoard()
{
assignedWork = await actionCallService.GetAssignedWorkByEmployeeId(SelectedCrewMemberId, FromDate, ToDate);
}
void ShowContextMenuWithItems(MouseEventArgs args, string visitId, string status, string nextStatus, string visitType)
{
var contextMenuItems = new List<ContextMenuItem>();
if (status != ACTION_STATUS.ActionCompleted)
{
var value = (visitId, status, visitType, nextStatus);
contextMenuItems.Add(new ContextMenuItem() { Text = nextStatus, Value = value });
ContextMenuService.Open(args, contextMenuItems, OnMenuItemClick);
}
}
void OnMenuItemClick(MenuItemEventArgs args)
{
var param = (string VisitId, string Status, string VisitType, string NextStatus) args.Value;
Task.Run(async () =>
{
switch (args.Text)
{
case "In Progress":
await actionCallService.InProgressCall(SelectedCrewMemberId, param.VisitId, param.VisitType, param.Status, FromDate, ToDate);
break;
case "Acknowledged":
await actionCallService.AcknowledgeCall(SelectedCrewMemberId, param.VisitId, param.Status, FromDate, ToDate);
break;
case "Completed":
await actionCallService.UpdateActionCallStatus(SelectedCrewMemberId, param.VisitId, param.Status, param.NextStatus, FromDate, ToDate);
break;
case "Rejected":
await actionCallService.UpdateActionCallStatus(SelectedCrewMemberId, param.VisitId, param.Status, param.NextStatus, FromDate, ToDate);
break;
default:
break;
}
await UpdateDispatchBoard();
});
ContextMenuService.Close();
InvokeAsync(StateHasChanged);
}
}
Upvotes: 0
Views: 577
Reputation: 381
The issue was on the OnMenuItemClick method. This method from radzen doesn't implement an async version of this method. When I changed Task.Run to InvokeAsync and added the rest of the code inside this, along with the StateHasChanged, everything works as expected.
InvokeAsync(async () =>
{
switch (args.Text)
{
case "In Progress":
await actionCallService.InProgressCall(SelectedCrewMemberId, param.VisitId, param.VisitType, param.Status, FromDate, ToDate);
break;
case "Acknowledged":
await actionCallService.AcknowledgeCall(SelectedCrewMemberId, param.VisitId, param.Status, FromDate, ToDate);
break;
case "Completed":
await actionCallService.UpdateActionCallStatus(SelectedCrewMemberId, param.VisitId, param.Status, param.NextStatus, FromDate, ToDate);
break;
case "Rejected":
await actionCallService.UpdateActionCallStatus(SelectedCrewMemberId, param.VisitId, param.Status, param.NextStatus, FromDate, ToDate);
break;
default:
break;
}
await UpdateDispatchBoard();
ContextMenuService.Close();
StateHasChanged();
});
Upvotes: 1
Reputation: 3
In your example you’re overriding OnParametersSetAsync but then inside you’re making a call to base.OnParametersSet(). The mismatch can be a problem. With onparametersset you have to make a call to the base.onparameterssetasync. That’s not the end all of your problem but it’s good practice not to mix up sync and a sync versions.
Upvotes: 0
Reputation: 30001
As you haven't shown all the necessary code this may be a process of elimination. However, the obvious first issue is OnMenuItemClick
, which I assume is the UI event handler for choosing an item in the dropdown menu.
async Task
so it returns a Task
to the UI Event handler that can be awaited.if all the page updates take place before the handler completes then it should work!
async Task OnMenuItemClick(MenuItemEventArgs args)
{
var param = (string VisitId, string Status, string VisitType, string NextStatus) args.Value;
switch (args.Text)
{
case "In Progress":
await actionCallService.InProgressCall(SelectedCrewMemberId, param.VisitId, param.VisitType, param.Status, FromDate, ToDate);
break;
case "Acknowledged":
await actionCallService.AcknowledgeCall(SelectedCrewMemberId, param.VisitId, param.Status, FromDate, ToDate);
break;
case "Completed":
await actionCallService.UpdateActionCallStatus(SelectedCrewMemberId, param.VisitId, param.Status, param.NextStatus, FromDate, ToDate);
break;
case "Rejected":
await actionCallService.UpdateActionCallStatus(SelectedCrewMemberId, param.VisitId, param.Status, param.NextStatus, FromDate, ToDate);
break;
default:
break;
}
await UpdateDispatchBoard();
ContextMenuService.Close();
}
Upvotes: 1