1

I'm extremely new to Blazor server and experimenting with web pages in general, and having trouble figuring out how to properly attach event handlers to a modal that should fire different actions based on the current page. I just want to be able to send the pages information as an email on submit, but it ends up sending all rendered pages emails as it considers each event triggered.

I'm using Radzen's Blazor DialogService and am trying to follow the pattern in their documentation - attaching the methods to it like this

protected override void OnInitialized()
{
  DialogService.OnOpen += Open;

  DialogService.OnClose -= Close;
  DialogService.OnClose += Close;
}

private void Open(string Title, Type type, Dictionary<string, object> parameters, DialogOptions options)
{
}

private void Close(dynamic result)
{
  if (result == true)
  {
      JS.InvokeAsync<string>("DisableDialogSubmit", "nhDialogSubmit");
      SendEmail();
  }
}
async void Submit()
{
    await SubmitModal();
    DialogService.OnClose -= Close;
}

void OnInvalidSubmit()
{

}

async Task SubmitModal() => await DialogService.OpenAsync("Confirm Submission", (ds =>
    @<div style="top: 25%">
        <p Style="margin-bottom: 1rem">Submit Form?</p>
        <div class="row">
            <div class="col-md-12">
                <RadzenButton id="nhDialogSubmit" Text="Submit" Disabled="false" Click="() => ds.Close(true)" Style="margin-bottom: 10px; width: 150px" />
                <RadzenButton Text="Cancel" Click="() => ds.Close(false)" ButtonStyle="ButtonStyle.Secondary" Style="margin-bottom: 10px; width: 150px" />
            </div>
        </div>
    </div>),
new DialogOptions() { Width = "350px", Top = "35%", Left = "25%" });

This code is copy pasted on each page with different logic in SendEmail() I got it working a little bit with that sort of ham fisted local event attaching and detaching, but it has side effects and I'm sure I'm using it completely wrong in the first place. I was hoping injecting the service as scoped would allow me to do this; would creating it as transient accomplish my implementation? I'm having a hard time finding the right things to search to manage events on a any service in a single page application, so any tips or pointers would be greatly appreciated!

Ubnik
  • 13
  • 4

1 Answers1

0

The documentation you point to uses @implements IDisposable and Dispose() and that makes much more sense.

I think the complete eventhandling should look like theirs, with no other += or -= anywhere else:

@implements IDisposable

...

@code {

    protected override void OnInitialized()
    {
        DialogService.OnOpen += Open;
        DialogService.OnClose += Close;
    }

    public void Dispose()
    {
        // The DialogService is a singleton so it is advisable to unsubscribe.
        DialogService.OnOpen -= Open;
        DialogService.OnClose -= Close;
    }

    ...    
}

Also, you shouldn't need JS and make the Submit() method an async Task, not async void.

H H
  • 263,252
  • 30
  • 330
  • 514
  • Now I feel silly, thank you so much! I'm almost certain an older version of this library did not implement IDisposable or Dispose(), but I should have caught that looking back at it. Now it's working much cleaner! – Ubnik Jun 29 '21 at 04:23
  • Regarding the use of JS - I had tried making Submit a task and disabling the buttons using the Components disabled flag and [StateHasChanged()/Task.Delay()](https://stackoverflow.com/questions/59201202/how-to-disable-hide-a-button-as-soon-as-clicked-in-blazor) but it still wouldn't behave. I think I messed up building off a library before properly understanding asp.net core. Confirmation this SHOULD be possible and the correct solution is so helpful though. Thank you again for solving this! – Ubnik Jun 29 '21 at 04:27