1
votes

I am building a sample component with a form that takes a credit card number. I am attempting to add an oninput event to the InputText component, which fails to function properly once attached. Without the event the form functions normally. It does not matter what the supplied method to the event does, it always fails to function properly.

code:

<Microsoft.AspNetCore.Components.Forms.EditForm Model="@card" OnValidSubmit="@HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <div>
        <div>
            <p>
                <label for="ccNumberId">Debit or Credit Card Number</label><br />
                <InputText id="ccNumberId" @bind-Value="card.Number" 
                     @oninput="@(e => FormatCreditCardNumber())"       /><br />
                @numberFormat
            </p>
            <p>
                <label for="ccYearId">Expiration Year</label><br />
                <InputText id="ccYearId" @bind-Value="card.ExpYear" />
            </p>
            <p>
                <label for="ccMonthId">Expiration Month</label><br />
                <InputText id="ccMonthId" @bind-Value="card.ExpMonth" />
            </p>
            <p>
                <label for="ccCvcId">CVC</label><br />
                <InputText id="ccCvcId" @bind-Value="card.Cvc" />
            </p>
        </div>
    </div>
    <button type="submit">Submit</button>
</Microsoft.AspNetCore.Components.Forms.EditForm>

@code {
    string numberFormat;

    private StripeChargeModel card = new StripeChargeModel();

    protected override void OnInitialized()
    {
    }

    private void HandleValidSubmit()
    {
        JSRuntime.InvokeVoidAsync("showOnToast", "#paymentToast");
    }

    private void FormatCreditCardNumber()
    {
        if (card.Number.Length == 4)
        {
            numberFormat = String.Empty;
            numberFormat = card.Number + "-";
        }
    }
}
1

1 Answers

2
votes

Note you're binding value by @bind-Value="card.Number" instead of by @bind-value:oninput. The @bind-Value directive binds value when value changes (i.e. the onchange event). And the oninput event fires before onchange: when the first keystroke event fires, the card.Number is null because the @onchange event has not arrived yet.

In order to fix that issue, you need prevent card.Number is null when checking card.Number.Length == 4 otherwise it will throw a System.NullReferenceException when the first keystroke event fires:

private void FormatCreditCardNumber()
{
    if (card.Number.Length == 4)
    if (card.Number?.Length == 4)
    {
        numberFormat = String.Empty;
        numberFormat = card.Number + "-";
    }
}