Musaffar Patel
Musaffar Patel

Reputation: 1342

Value of of counter parameter not incrementing when an EventCallback is invoked

I have run into a strange problem which presevnts the value of a counter incrementing when the value is accessed as a paremeter via a component instance. The code should hopefully help describe the problem:

Index.razor

<MyComponent @ref="MyComponent1" Test=1 OnChange="OnChange"></MyComponent>

Index.razor.cs

namespace MyApp.Web.Pages.Transactions
{
    public partial class List : ComponentBase
    {
        private MyComponent MyComponent1 { get; set; } = default!;

        public void OnChange()
        {
            System.Console.WriteLine(MonthPicker1.Test);
        }
    }
}

MyComponent.razor

<button @onclick="@(() => OnClick()">press me</button>

MyComponent.razor.cs

namespace Accounting.Web.Components.MonthPicker
{
    public partial class MonthPicker
    {
        [Parameter]
        public EventCallback OnChange { get; set; } = default!;
    
        [Parameter]
        public int Test { get; set; } = 1;
    
        private void OnClick(NavigationDirection direction)
        {
            Test++;
            OnMonthPickerChange.InvokeAsync();
        }
    }
}

When the OnClick event is called in the child component, the value is Test should be incremented each time, but it always outputs the value 2 when the value is accessed through the component instance reference in index.razor.cs by invoking on the OnChange event callback. So it seems the value is increased only once.

If I remove the callback in MyComponent.razor.cs, then the value of Test will increment indefinitely as it should.

Why is the act of invoking the callback preventing Test from incereasing beyond the value of 2?

---- EDIT -----

Not long after posting the question it occurred to me that somehow the value of test is being reset so I remove passing the parameter through the component tag as follows:

<MyComponent @ref="MyComponent1" OnChange="OnChange"></MyComponent>

Notice the removal "Test=1" from the above tag. When doing this the value of Test is incremented indefinitely as expected.

So now the question, is what can I do to allow a default for value for Test to be passed as the parameter without having it reset when I invoke the callback?

Upvotes: 0

Views: 121

Answers (1)

Neil W
Neil W

Reputation: 9122

As you've identified, each time an event is raised the parameters are passed back down.

Try this:

namespace Accounting.Web.Components.MonthPicker
{
    public partial class MonthPicker
    {
        [Parameter]
        public EventCallback OnChange { get; set; } = default!;
    
        [Parameter]
        public int InitialValue { get; set; }

        public int Test { get; private set; }
    
        bool _initialised = false;

        protected override void OnParametersSet()
        {
            if (!_initialised)
            {
                Test = InitialValue;

                _initialized = true;
            }
        }
 
        private void OnClick(NavigationDirection direction)
        {
            Test++;
            OnChange.InvokeAsync();
        }
    }
}

And then set InitialValue Parameter from parent.

Upvotes: 2

Related Questions