0
votes

So I'm new to Blazor and I've just found out about CascadingValue and their possible use for showing error messages. I am creating an Outlook Add In for saving mails and attachments in Sharepoint, so I'm dynamically retrieving the current Outlook mail using Office-js and JSInterop, such that my Add In always uses the selected mail. But now that I'm trying to implement a cascading component for error messages I've run into problems with StateHasChanged.

Following code is my cascading error component:

<CascadingValue Value=this>
    @ChildContent
</CascadingValue>
<div class="error-container @(ErrorMessage == null ? "hidden" : "")">
    <span class="error-message">
        @ErrorMessage
    </span>
    <a class="dismiss-error" @onclick="DismissError">x</a>
</div>

@code {
    [Parameter]
    public RenderFragment ChildContent { get; set; }
    public string ErrorMessage { get; set; }

    public void ProcessError(Exception ex)
    {
        ErrorMessage = ex.Message;
        StateHasChanged();
    }

    public void DismissError()
    {
        ErrorMessage = null;
        StateHasChanged();
    }
}

And the component I'm having troubles with (atleast the important parts):

<div>
    {Showing details from OutlookMail here}
</div>
@code {
    [CascadingParameter] public Error Error { get; set; }
    public OutlookMail OutlookMail { get; set; }
    private static Action<OutlookMail> _receiveMailAction;
    protected override async Task OnInitializedAsync()
    {
        _receiveMailAction = UpdateMail;
        await base.OnInitializedAsync();
    }
    private void UpdateMail(OutlookMail mail)
    {
        InvokeAsync(() =>
        {
            OutlookMail = mail;
            StateHasChanged();
        });
    }
    [JSInvokable]
    public static void ReceiveMail(OutlookMail mail)
    {
        _receiveMailAction?.Invoke(mail);
    }
    public async Task MethodWithError()
    {
        try
        {
            await DoStuffWithPossibleError();
        }
        catch (Exception e)
        {
            Error.ProcessError(e);
        }
    }
}

Everything works fine until Error.ProcessError gets called and the error message is shown, after that StateHasChanged stops rerendering my component which gives inconsistent data to the users.

I am probably doing something wrong, since I can't really find anyone else with the same problem, but I'm not seeing it, so I'm hoping someone on here has a better understanding of where things are going wrong, or maybe even a better way of going about showing error messages if the problem is with using CascadingValue like this.

All the help is appreciated.

Edit 1: After some more looking into this, it seems that it's actually not updating OutlookMail, even when I move it outside of InvokeAsync. So there might be something weird happening with instances of my component

1

1 Answers

0
votes

After my first edit, I found out it was indeed a problem with instances, since I'm overwriting a static Action within OnInitialized, each time it creates a new instance, the old instances no longer works. And the code which returned the error happened to have a auth dialog with a redirect callback to the same page, it closes directly after, but loading the page actually creates a new instance of my component, which in turn invalidates the one my user works with. So I'll probably just have to create a singleton service that handles the incoming mail data, so that my component can always access the correct data.