Search code examples
c#.netblazortelerik

Razor page component OnParametersSetAsync is not refreshing after change in it's parent component


I have a razor page called _Upsert page which takes an argument and passes the value to child component by calling the child component and passing the value through it. Normally it should update the child component by calling it's OnParametersSetAsync method as soon as the parent component makes any change to the child component value. But in this code it is not calling OnParametersSetAsync. I have tried everything. Please help me.

Child page - TelerikTextAreaQuickCode.razor

@using MOM.Model.Setup
@using Telerik.FontIcons;
@using MOM.Model.Common;
@using BlazorBootstrap;
@using Telerik.Blazor.Components
@using System.Threading.Tasks
@using Microsoft.JSInterop

@inject MOM.Service.Setup.Interfaces.IQuickCodeService _quickCodeService;
@inject MOM.Service.Setup.Interfaces.IBranchService _branchService;

<TelerikTextArea Value="@TextValue" ResizeMode=TextAreaResizeMode.Auto Id="@Id" Size="@size" Rounded="@size" ValueChanged="@FillValueByCode" ValueExpression="@(() => TextValue)" />
  
@code {

    [Parameter]
    public List<byte> selectedBranchIds { get; set; } = new List<byte>();

    public EventCallback<List<byte>> selectedBranchIdsChanged { get; set; }

    private List<QuickCodeDTO>? quickCodeItems { get; set; } = new List<QuickCodeDTO>();
    private List<QuickCodeDTO>? quickCodeFiltered { get; set; } = new List<QuickCodeDTO>();
    public List<BranchDropListDTO>? BranchItems { get; set; }
    private string _value;


    protected override async Task OnInitializedAsync()
    {
        try
        {
            TextValue = Value;
            var branchTask = _branchService.GetUserBranches();
            var quickCodeTask = _quickCodeService.GetAllForDropDown();
            await Task.WhenAll(branchTask, quickCodeTask);
            var BranchResponse = await branchTask;
            var quickCodeResponse = await quickCodeTask;
            if (BranchResponse.Message == "SUCCESS")
            {
                BranchItems = BranchResponse.Data;
            }
            if (quickCodeResponse.Message == "SUCCESS")
            {
                quickCodeItems = quickCodeResponse.Data;
            }
            FilterCode();

        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    protected override async Task OnParametersSetAsync()
    {
        try
        {

            if (selectedBranchIds.Count() > 0)
            {
                quickCodeFiltered = quickCodeItems.FindAll(x => x.BranchAccessDTOs.Any(y => y.IsAccess && selectedBranchIds.Contains(y.BranchId)));
            }
            else
            {
                quickCodeFiltered = quickCodeItems.FindAll(x => x.BranchAccessDTOs.Any(y => BranchItems.Select(x => x.Id).Contains(y.BranchId)));
            }
        }
        catch(Exception ex)
        {
            throw ex;
        }
    }

    private void FillValueByCode(string newValue)
    {
        if (newValue.Contains("//"))
        {
            string[] newStrArr = newValue.Split('/');
            string[] codes = newStrArr[0].Split(' ');
            string quickCode = codes[codes.Length - 1];
            var result = quickCodeFiltered?.FirstOrDefault(x => x.Code.ToLower().Trim() == quickCode.ToLower().Trim());
            if (result != null)
            {

                TextValue = newValue.Replace($"{codes[codes.Length - 1].ToString()}//", result.Name);
            }
            else
            {
                TextValue = newValue;
            }
        }
        else
        {
            TextValue = newValue;
        }
    }
}

Parent page - _Upsert.razor

<FormGroup Columns="@subGroupLayoutColumnsCountupsert" ColumnSpacing="25px" Class="legende ">
<FormItem ColSpan="2">
    <Template>
        <label for="Name" class="k-label k-form-label">@MOM.Alias.Common.DTO.Remarks</label>
            <TelerikTextAreaQuickCode selectedBranchIds="@branchIds" @bind-Value="@dto.Remarks" Id="Remarks" />
        <TelerikValidationTooltip For="@(() => dto.Remarks)" TargetSelector="#Remarks" />
    </Template>
</FormItem>
@if (IsMultipleBranch == 1)
{
        <FormItem ColSpan="2">
        <Template>
                <BranchAccessNew @ref="@branchRef" ScreenName="@MOM.UI.Client.Constants.GRID.LeadType" ShowCount="true" BranchAccessDTOs="@dto?.BranchAccessDTOs" OnDialogueOpen="@((bool value) => { isChildDialogueOpen = value; })" onStateChange="@(()=> { dialogRef.Refresh(); })" onBranchChange="@GetbranchIds"></BranchAccessNew>
        </Template>
    </FormItem>
}
</FormGroup>

The method GetBranchIds hits when I select another branch but from branchAccessNew but it does not hit the child page component.

Please help me with this.


Solution

  • Just changing the value of a property/field on the parent that is used as a parameter for a child will not trigger a render of the child.

    In normal circumstances a component is mutated by either:

    • a UI event, or
    • a normal event from a service.

    In the case of the former, the render is built into the component's UI handling code.

    In the case of the later, you need to call StateHasChanged manually in the event handler. You may need to use InvokeAsync(StateHasChanged) if the event is handled on a different thread.

    I can't see either in the code you've shown in the question. I may of course be blind.