MatSnackbar not updating MatSnackBarContent

381 Views Asked by At

In my code when opening a MatSnackBar multiple times the content that is displayed in the SnackBar does not update as I suppose it should. Example:

@page "/"

    <div> count value: @count </div>
    <MatButton OnClick="ButtonClick">Open</MatButton>
    <MatSnackbar @bind-IsOpen="@snackBarIsOpen">
        <MatSnackbarContent>Count: @count</MatSnackbarContent>
        <MatSnackbarActions>
            <MatButton Raised="true" @onclick="() => { snackBarIsOpen = false; }" >Close</MatButton>
        </MatSnackbarActions>
    </MatSnackbar>

    @code
    {
        bool snackBarIsOpen = false;
        int count = 0;

        void ButtonClick()
        {
            snackBarIsOpen = true;
            count++;
            this.StateHasChanged();
        } 
    }

When clicking multiple times on the button, the SnackBar always displays "Count: 1". What am I doing wrong?

1

There are 1 best solutions below

1
On

When you run your home page for the first time the only visible element seen is MatButton. MatSnackbar is not seen because its parameter attribute value is false:

@bind-IsOpen="@snackBarIsOpen"

bool snackBarIsOpen = false;

When you click on MatButton, the ButtonClick event handler is executed, snackBarIsOpen == true, and the MatSnackbar component is 're-rendered'. But now the IsOpen parameter value of the component is true, and thus it is displayed with the content of the MatSnackbarContent component. Below is the code that does this:

BaseMatSnackbar.cs (Note the comments are mine...)

[Parameter]
        public bool IsOpen
        {
            get => _isOpen;
            set
            {
                // When the component is created the value of IsOpen is false 
                // and the parameter value passed to it is also false, so the 
                // code within the if block is not executed.
                if (IsOpen != value)
                {
                    _isOpen = value;
                    // After clicking the MatButton IsOpen != value, and thus 
                    // this code is executed by JavaScript to display the 
                    // component
                    CallAfterRender(async () =>
                    {
                        await JsInvokeAsync<object>("matBlazor.matSnackbar.setIsOpen", Ref, value);
                    });
                }
            }
        }

When you click the MatButton for the next time IsOpen == value, the above if block is not executed, the condition being IsOpen != value, in other words, why display the component if it is already displayed.

Now, whenever, you hit the MatButton, the local variable is incremented, but the content of the MatSnackbarContent remains the same after the first click: "Count: 1", in other words, the MatSnackbarContent component is not rerendered with the new value of count.

I'll post here some of the relevant code involved, and perhaps you can shed some new light about those components. I'm not familiar with MatBlazor, and I'd rather learn the core of Blazor first...

https://github.com/SamProf/MatBlazor/blob/master/src/MatBlazor.Web/src/matSnackbar/matSnackbar.js

https://github.com/SamProf/MatBlazor/blob/master/src/MatBlazor/Components/MatSnackbar/MatSnackbar.razor

https://github.com/SamProf/MatBlazor/blob/master/src/MatBlazor/Components/MatSnackbar/BaseMatSnackbar.cs

Hope this helps...