Search code examples
c#blazordevexpressblazor-server-sidedevexpress-blazor

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


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.


Solution

  • 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();
    }