Is it possible to load different set of data in child component, based on parameter that is changed in parent component, in Blazor Server app?

Viewed 197

I am working on a Blazor server app.

I am trying to pass a parameter (int platformId) from parent component to child component. The platformId defines the platform, and changing it should result in a different set of data rendered in child component. A button is used to toggle between 2 different platformIds.

I pass the platformId successfully to child component as it's changed, but so far I couldn’t find the way to populate listOfGrades with data from changed platform. It seems that once the PlatformId is set as here <ChildComponent @ref="childComponent1" PlatformId="platformId" /> it just cannot be changed.

Parent component:

@code{
    int platformId = 1;
    bool defaultSelected = false;

    public void ToggleId()
    {
        defaultSelected = !defaultSelected;
        SetPlatformId();
    }

    public void SetPlatformId()
    {
        if (defaultSelected)
            platformId = 1;
        else
            platformId = 2;
    }
}

Child component:

@code{
    public List<GradeModel> listOfGrades;

    [Parameter]
    public int PlatformId { get; set; }

    protected override async Task OnInitializedAsync()
    {
        listOfGrades = await gradesService.GetAllGradesAsync(platformId).ConfigureAwait(false);
    }
}
2 Answers

It can, but you're looking at the wrong event. OnInitializedAsync is called exactly once (or twice with server prerendering) when the component is first created. You're looking for OnParametersSetAsync. They're described in ASP.NET Core Razor component lifecycle:

OnInitialized and OnInitializedAsync are invoked when the component is initialized after having received its initial parameters in SetParametersAsync.

On the other hand:

OnParametersSet or OnParametersSetAsync are called:

  • After the component is initialized in OnInitialized or OnInitializedAsync.
  • When the parent component rerenders and supplies:
    • Known primitive immutable types when at least one parameter has changed.
    • Complex-typed parameters. The framework can't know whether the values of a complex-typed parameter have mutated internally, so the framework always treats the parameter set as changed when one or more complex-typed parameters are present.

Just change the override to be OnParametersSetAsync and your current logic should work as expected.

I recommend you read the linked article on lifecycle, for me it really help to understand how the Blazor magic happens.

I managed to get what I wanted, by using additional method that will be called both from Oninitialized, and when button is clicked:

public List<GradeModel> listOfGrades;
int platformId = 0;
private int PlatformIdfromIndex { get; set; }

protected override async Task OnInitializedAsync()
{
    await LoadComponent(platformId);
}

public async Task LoadComponent(int platformId)
{
    listOfGrades = await gradesService.GetAllGradesAsync(platformId);
}

async Task OnPlatformButtonChange(object value)
{
    PlatformId = (int)value;
    await LoadComponent(PlatformId);
}
Related