Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state

1k views Asked by At

I have a child component in Blazor Server, which displays a table. On click of a row in that table, I have the following handler method and event callback to send the data to the parent component (which wraps the child component in a popup that needs to be toggled when new data comes through).

The object get/set comes from DevExpress and I can't seem to make that method async without throwing an error, yet the event callback requires async.

[Parameter]
public EventCallback<DataObj> OnDataObjSelection { get; set; }
DataObj _selectedDataObject { get; set; }

object SelectedDataObject
    {
        get
        {
            return _selectedDataObject;
        }
        set
        {
            _selectedDataObject = value as DataObj;
            new Task(async () =>
            {
                await OnDataObjSelection.InvokeAsync(_selectedDataObject);
            }).Start();
        }
    }

In the parent component, I have this function triggered on the event callback (which will hide the popup wrapping the child component if it's visible):

 async void DataObjSelectionChanged(DataObj dataObj)
        {
            _currentDataObj = dataObj;
    
            if (_showPopup)
            {
                await InvokeAsync(() =>
                {
                    _showPopup = false;
                    StateHasChanged();
                });
            }
        }

Yet, I'm getting the following error: Use InvokeAsync() to switch execution to the Dispatcher when triggering rendering or component state Blazor Server

Anyone know how to get around this? I thought I had the syntax correct, but apparently not.

1

There are 1 answers

2
MrC aka Shaun Curtis On BEST ANSWER

As has been alluded to above, you are overcomplicating this.

[Parameter]
public EventCallback<DataObj> OnDataObjSelection { get; set; }
DataObj _selectedDataObject { get; set; }

object SelectedDataObject
    {
        get =>  _selectedDataObject;
        set
        {
            _selectedDataObject = value as DataObj;
            OnDataObjSelection.InvokeAsync(_selectedDataObject);
        }
    }

And:

private void DataObjSelectionChanged(DataObj dataObj)
{
    _currentDataObj = dataObj;
    if (_showPopup)
         StateHasChanged();
}