1

When a parameter in my Blazor component is changed, I want to do some stuff. If it's not too much, I could do it in the setter. However, if I want to do something more, maybe in a background thread, I can't (shouldn't) do it in the setter.

I know about OnParameterSetAsync, but how do I know what parameter was set? I can get it to work (see below), but was wondering if there is a better way?

Here is my component:

// ReactOnParameterUpdate.razor
<h2>@Message</h2>

@code
{
    [Parameter]
    public string Input { get; set; }

    protected string Message = "";
    private string _previousInput = null;

    protected override async Task OnParametersSetAsync()
    {
        if (_previousInput != Input)
        {
            _previousInput = Input;
            await SomeAsyncMethod();
        }
    }

    private async Task SomeAsyncMethod()
    {
        Message = $"Async method was called at {DateTime.Now}";
        await Task.CompletedTask;
    }
}

And the component is used here:

// Index.razor
@page "/"

<div class="input-group mb-3">
    <div class="input-group-prepend">
        <span class="input-group-text">Input:</span>
    </div>
    <input type="text" class="form-control" @bind="@Input">
</div>

<ReactOnParameterUpdate Input=@Input></ReactOnParameterUpdate>

@code
{
    protected string Input;
}

EDITED: From suggestions below and for completeness, here is how you can use SetParametersAsync:

    public override async Task SetParametersAsync(ParameterView parameters)
    {
        foreach (var param in parameters)
        {
            if (param.Name == nameof(Input) && (string)param.Value != Input)
            {
                await SomeAsyncMethod();
            }
        }
        await base.SetParametersAsync(parameters);
    }
1
  • 1
    Jeremy Likeness has a blog post outlining using INotifyPropertyChanged and an MVVM pattern that you may be able to modify for this. See the post here
    – Nik FP
    Commented Jun 17, 2020 at 13:52

2 Answers 2

4

You can use a loop to see what properties have been changed. Hope this helps.

@code {

    [Parameter]
    public Foo Foo { get; set; }

    public override async Task SetParametersAsync(ParameterView parameters)
    {
        foreach(var prm in parameters)
        {
            Console.WriteLine($"Name: {prm.Name}");
            Console.WriteLine($"Value: {prm.Value?.ToString()}");
        }

        await base.SetParametersAsync(parameters);
    }
}
3
  • Thank you for your input. Had a read about the Blazor lifecycle, and in my case I don't need to know that early in the lifecycle, so OnParametersSetAsync is probably just as good. I was hoping there was a totally different way to do this, but there probably isn't(?) Commented Jun 17, 2020 at 12:34
  • NB: With SetParametersAsync I don't need the extra _previousInput variable, so it was helpful :-) Commented Jun 17, 2020 at 12:45
  • I feel it's worth mentioning that if your parameters are coming from a parent page or component, and you have multiple parameters, multiple parameters will be provided in your ParameterView object, even ones that don't change. In addition, in this overwritten function at the point where you see that there's a difference between the new parameter and the one coming in, the value hasn't yet changed and so executing a function here off of a difference will be running based on non changed values. Commented Oct 19, 2023 at 19:35
0

SetParametersAsync is what you need. You can do this

string previousInput = Input;
await SetParametersAsync(parameters);
if (Input != previousInput)
{
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.