Client Side Blazor form submit twice

Viewed 864

In a client side blazor app I have a form that gets submitted. In the onValidSubmit of the form I make a async call out to the server to post the data. When the post comes back I tell the modal window to close. However, the modal window does not close until I click the submit button again. If I remove the async post then the modal window closes on the first submit. Does anyone know what might be happening here?

page with form

<ModalWindow  @bind-ShowWindow="ShowAddwindow">
    <Content>
        <EditForm Model="@Orig" OnValidSubmit="@AddOrig">
            <DataAnnotationsValidator />
            <ValidationSummary />
            <ServerSideValidator />

            <InputText @bind-Value="Orig.Name" id="origName" />
            <button type="submit" class="btn btn-primary">Add</button>
        </EditForm>
    </Content>
</ModalWindow>

private async void AddOrig()
{
    if(!string.IsNullOrEmpty(Orig.Name))
    {
        ResponseContent<bool> result = await httpUtil.PostRequest<bool>("postData", Orig);

        switch(result.Status)
        {
            case System.Net.HttpStatusCode.Unauthorized:
                
                break;

            case System.Net.HttpStatusCode.BadRequest:

                serverSideValidator.DisplayErrors(result.Errors);

                break;

            default:
                ShowAddwindow = false;
                Orig = new Organization();
                break;
        }


    }
}

Modal.razor

<div class="modal" style="display: @_displayType;">

<!-- Modal content -->
<div class="modal-content">
    <span class="close" @onclick="Close">&times;</span>
    <div>@Content</div>
</div>
@code {
    private bool _showWindow;
    [Parameter]
    public bool ShowWindow
    {
        get => _showWindow;
        set
        {
            _showWindow = value;
            _displayType = value ? "block" : "none";
        }
    }

    [Parameter]
    public EventCallback<bool> ShowWindowChanged { get; set; }

...
}
2 Answers

This code: private async void AddOrig()

Should be private async Task AddOrig()

If you don't use Task as the return object the runtime cannot know when your async call has finished, the result of which is no rendering (as the StateHasChanged method is not automatically called), which means your modal is still visible

Always avoid async void:

private async Task AddOrig()
{
   ...
}

With async void the (re-)rendering happens when you await the HttpClient call. You could fix it with an extra StateHasChanged() but there is no reason for async void here.

Related