Search code examples
validationblazorblazor-server-side

Blazor - Manually trigger validation on multiple child component instances


I have a page with a model that has a list of Payments. In the parent page I have code to add or remove payments. When the page loads, there is one payment already in the list. This list of payments is actually a child control added to the parent page.

Parent page markup (partial for brevity)

@if (NewClaim.PaymentsList.Any())
{
    @foreach (var payment in NewClaim.PaymentsList)
    {
        <Payment PaymentModel="payment" @ref="childComponentPayment"></Payment>
        <MudIconButton Icon="fas fa-solid fa-minus"
                       aria-label="Delete Address"
                       Color="Color.Error"
                       Size="Size.Small"
                       Variant="Variant.Outlined"
                       OnClick="@(() => RemovePayment(payment))">
        </MudIconButton>
    }
}

Parent Code-Behind

    protected Payment childComponentPayment;
    protected List<Payment> childComponentPayments;

protected override void OnInitialized()
{
    if (NewClaim.PaymentsList is null)
    {
        NewClaim.PaymentsList = new List<PaymentInfo>();
        childComponentPayments = new List<Payment>();
    }

    AddPayment();
}

    public void AddPayment()
    {
        NewClaim.PaymentsList.Add(new PaymentInfo());
        childComponentPayments.Add(childComponentPayment);
    }

    protected void RemovePayment(PaymentInfo payment)
    {
        NewClaim.PaymentsList.Remove(payment);
        childComponentPayments.Remove(childComponentPayment);
    }

    protected async Task ValidateClaim(EditContext editContext)
    {
        var claimDisplayModel = (NewClaimModel)editContext.Model;
        foreach (Payment payment in childComponentPayments) {
            if (payment is not null)
            {
                payment.Validate();
            }
         }
    }

When the form is valid, I want to validate each instance of child component, however, when the page first runs, the first instance is always null. This is really where my questions lies. I am not sure why it is null, and how to fix it. The loop works and validates all subsequent instances as long as I skip the first one.

My child component is just a simple EditForm with 2 fields with validation(data annotations). This is the code-behind of that component:

    [Parameter]
    public PaymentInfo PaymentModel { get; set; } = new();
    protected EditContext EC { get; set; }

    protected override async Task OnInitializedAsync()
    {
        EC = new EditContext(PaymentModel);
        //base.OnInitialized();
    }

    public void Validate()
    {
        var x = EC.Validate();

    }

This works exactly as I hoped it would except for the first null instance. Can anyone please explain why that is, and how I may be able to fix it? Perhaps there is a better way to accomplish what I want to do?

Thanks in advance for any help.


Solution

  • A coworker of mine wound up implementing complex object validation using

         <ObjectGraphDataAnnotationsValidator/>
    

    There is a lot of back and forth on this object in the .NET 6 but it seems to be working for us. I have not used .NET 7 or 8 as of yet and not sure if this is considered more stable for the newer frameworks. If anyone has anymore input on this validator tag, please post

    Thank you