[Solved] TelerikTextBox - ValueChanged not fired before form submit when DebounceDelay is set

1 Answer 13 Views
TextBox
Alexey
Top achievements
Rank 1
Iron
Iron
Alexey asked on 20 Apr 2026, 06:35 PM

Description

When TelerikTextBox is used inside an HTML <form> with DebounceDelay configured, submitting the form (e.g. pressing Enter or clicking a submit button) races against the debounce timer. The ValueChanged callback has not yet fired by the time the form's onsubmit handler runs, so the component's internal state still holds the previous value — not the one the user typed.

The only workaround we found is to await Task.Delay(DebounceDelay + buffer) inside the submit handler to artificially wait for the debounce window to expire before reading the value. This is fragile, unreliable under load, and a clear code smell.

Expected behavior

When the form is submitted, TelerikTextBox should immediately flush its pending debounced value (i.e. fire ValueChanged synchronously or at least before the browser submit event propagates), so the calling component has the correct, up-to-date value at the moment the submit handler runs.

Alternatively, TelerikTextBox should expose a way to imperatively commit the current value (e.g. a public CommitValue() method, or a @ref-accessible flush API).



Steps to reproduce

  1. Place a TelerikTextBox with DebounceDelay inside an HTML <form>.
  2. Bind the value using Value + ValueChanged (two-way binding pattern).
  3. Add a submit button or handle Enter via @onsubmit.
  4. Type text quickly and immediately press Enter before the debounce window expires.
  5. Observe that ValueChanged has not fired yet, so the submitted value is stale.


Minimal reproducible example:


@* SearchInput.razor *@
<form @onsubmit="HandleFormSubmit" @onsubmit:preventDefault>
    <TelerikTextBox Value="@_value"
                    ValueChanged="@HandleValueChanged"
                    Placeholder="Search..."
                    DebounceDelay="@DebounceDelay" />
    <button type="submit">Search</button>
</form>
<p>Submitted value: <strong>@_submittedValue</strong></p>
<p>Current internal value: <strong>@_value</strong></p>
@code {
    // Simulates a real-world DebounceDelay parameter passed in by a parent
    private int DebounceDelay { get; set; } = 300;
    private string _value = string.Empty;
    private string _submittedValue = string.Empty;
    private void HandleValueChanged(string value)
    {
        // This fires only after DebounceDelay ms have passed since the last keystroke.
        // If the user presses Enter before that window expires, this has NOT been called yet.
        _value = value;
    }
    private async Task HandleFormSubmit()
    {
        // PROBLEM: at this point, if the user typed and immediately hit Enter,
        // _value may still hold the OLD value because HandleValueChanged
        // hasn't been called yet (debounce hasn't fired).
        // WORKAROUND (bad practice — fragile, timing-dependent):
        // await Task.Delay(DebounceDelay + 50);
        // What we WANT: a way to tell TelerikTextBox "flush now"
        // so that _value is guaranteed to reflect what the user typed.
        _submittedValue = _value; // may be stale without the Task.Delay hack
        await Task.CompletedTask;
    }
}

To observe the bug without the workaround:

  1. Remove / comment out the Task.Delay line.
  2. Set DebounceDelay to something perceptible like 300 ms.
  3. Type quickly in the box and press Enter immediately.
  4. "Submitted value" will show the previous value, not what you just typed.

Current workaround


private async Task HandleFormSubmit()
{
    // Must wait for debounce to expire before _value is reliable
    if (DebounceDelay > 0)
        await Task.Delay(DebounceDelay + 50); // 50 ms buffer for safety

    await OnSubmit.InvokeAsync();
}

This is problematic because:

  • It introduces an artificial, fixed delay on every form submit (even when no debounce is pending).
  • The buffer (+50 ms) is arbitrary and can still fail under CPU load or slow devices.
  • It makes the submit handler non-deterministic and hard to test.

What we are asking for

One of the following solutions:

  1. Automatic flush on submit — TelerikTextBox should detect that the parent form is being submitted (via a form context or EditContext) and immediately fire ValueChanged with the current raw input value, bypassing the remaining debounce wait.

  2. Imperative flush via @ref — Expose a FlushValue() / CommitValue() method on the component ref so the consumer can call it before reading the bound value:


@* Desired API *@
<TelerikTextBox @ref="_textBoxRef" ... DebounceDelay="300" />

private TelerikTextBox _textBoxRef;

private async Task HandleFormSubmit()
{
    await _textBoxRef.FlushValueAsync(); // fires ValueChanged immediately
    _submittedValue = _value;            // now guaranteed to be up-to-date
}

1 Answer, 1 is accepted

Sort by
1
Dimo
Telerik team
answered on 21 Apr 2026, 06:17 AM

Hi Alexey,

In such scenarios the solution is to set zero DebounceDelay to the TextBox.

On a side note, please ask the license holder at your company to assign you a Telerik UI for Blazor license. This will ensure your account is compliant to our license agreement and allow you to use technical support from us.

Regards,
Dimo
Progress Telerik

Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.

Denis
Top achievements
Rank 1
commented on 21 Apr 2026, 10:29 AM | edited

Hi Dimo,

Setting DebounceDelay to zero is not a viable solution,
Denis
Top achievements
Rank 1
commented on 21 Apr 2026, 10:29 AM

Hi Dimo,

Setting DebounceDelay to zero is not a viable solution, because even when DebounceDelay is set to zero, the component does not automatically update the Value or trigger the ValueChanged handler (or similar handlers).

My conclusion is based on the TelerikTextBox source code handler:

public void OnInput(ChangeEventArgs args)
        {
            if (DebounceDelay == 0)
            {
                UpdateValue(args.Value.ToString());
            }
            else
            {
                _debouncer.Debounce(
                () =>
                {
                    return this.InvokeAsync(() => UpdateValue(args.Value.ToString()));
                },
                DebounceDelay);
            }
        }
Can you please fix issue:  ValueChanged not fired before form submit when DebounceDelay is set.

Regards,
Denis Sikic


Alexey
Top achievements
Rank 1
Iron
Iron
commented on 21 Apr 2026, 10:31 AM

Hi Dimo and Telerik Team,

Set zero for DebounceDelay is not fire automatically any handlers of the TelerikTextBox like: ValueChanged or OnChang. As result I cannot ability to have actual value from TelerikTextBox when I'm handling submit form. 

So I is not suitable to set zero for DebounceDelay.

Dimo
Telerik team
commented on 21 Apr 2026, 10:39 AM

>> even when DebounceDelay is set to zero, the component does not automatically update the Value or trigger the ValueChanged handler (or similar handlers).

This is not normal and suggests another more serious problem with the app, for example, missing interactive render mode.

Alexey
Top achievements
Rank 1
Iron
Iron
commented on 21 Apr 2026, 11:21 AM | edited

Hi Dimo and Telerik Team

>> This is not normal and suggests another more serious problem with the app, for example, missing interactive render mode.

No . You can try to run my above clear example or it:

@* SearchInput.razor *@
<form @onsubmit="HandleFormSubmit" @onsubmit:preventDefault>
    <TelerikTextBox Value="@_value"
                    ValueChanged="@HandleValueChanged"
                    Placeholder="Search..."
                    DebounceDelay="@DebounceDelay" />
    <button type="submit">Search</button>
</form>
<p><strong>@_submittedValue</strong></p>
<p>Current internal value: <strong>@_value</strong></p>
@code {
    private int DebounceDelay { get; set; } = 15000; // 15 seconds
    private string _value = string.Empty;
    private string _submittedValue = string.Empty;
    private void HandleValueChanged(string value)
    {
        _value = value;
    }
    private async Task HandleFormSubmit()
    {
        try {
            DebounceDelay = 0;
            var time = DateTime.UtcNow.ToString("mm:ss");
           _submittedValue = $"Submitted value:{_value} at time: {time}";
        }
        finally
        {
            DebounceDelay = 15000; //set back 15 seconds
        }
       await Task.CompletedTask;
    }
}

or see attached gif animation with this example


Can you please fix issue:  ValueChanged not fired before form submit when DebounceDelay is set.
Dimo
Telerik team
commented on 21 Apr 2026, 11:33 AM

You have DebounceDelay of 10 seconds for the TextBox. Test this:

https://blazorrepl.telerik.com/GgkowvPv32E798Fb30

Alexey
Top achievements
Rank 1
Iron
Iron
commented on 21 Apr 2026, 11:57 AM

You absolutely right for DebounceDelay is 10 it is for demo.
I have gif animation with less debounce value like 5 seconds :


But on my real application i have DebounceDelay is 1 second and when my users Press key ENTER after typing they have  wrong value.

Can you please fix issue:  
ValueChanged not fired before form submit when DebounceDelay is set. 
Dimo
Telerik team
commented on 21 Apr 2026, 12:11 PM

The TextBox doesn't know about the form, so I am not sure we can integrate the textbox with the Form Submit event. However, we have this related feature request, which may do the job:

https://feedback.telerik.com/blazor/1683363-make-the-onchange-event-receive-the-immediate-value-when-the-debouncedelay-is-greater-than-0

Tags
TextBox
Asked by
Alexey
Top achievements
Rank 1
Iron
Iron
Answers by
Dimo
Telerik team
Share this question
or