Declined
Last Updated: 23 Aug 2024 11:55 by ADMIN
Felix Bohn
Created on: 30 Jul 2024 06:40
Category: Stepper
Type: Bug Report
0
Bug in the TelerikStepper in Blazor

Hi, I just came accross a bug in the TelerikStepper.

I try to create a custom version that switches to a custom success icon after a step is completed.
It contains the following codesnippets:


<TelerikStepper Linear="true" ValueChanged="@HandleValueChanged">
    <StepperSteps>
        @for (int i = 0; i < IsValidArray.Length; i++)
        {
            <StepperStep Valid="@IsValidArray[i]"></StepperStep>
        }
    </StepperSteps>
</TelerikStepper>

@code {
    bool?[] IsValidArray = [null, null, null, null];

    public void HandleValueChanged(int index)
    {
        for (int i = 0; i < IsValidArray.Length; i++)
        {
            IsValidArray[i] = index > i ? true : null;
        }
    }
}

 

Forward it works like expected:


When moving backwards it behaves strange:

Except if you are debugging (Visual Studio debugger), then everything works as expected:


Same thing can be achived when not debugging but clicking on the step a second time

3 comments
ADMIN
Hristian Stefanov
Posted on: 23 Aug 2024 11:55

Hi Felix,

I apologize for my previous message not being accurate that the actual important part of the configuration is the Task.Delay. Let me provide a brief explanation below on why this is expected.

The example works correctly only when you add Task.Delay in the HandleValueChanged method because of the way Blazor handles state updates and component re-rendering.

  • Blazor Rendering and State Updates: Blazor components re-render when their state changes. In your code, the "HandleValueChangedmethod updates the "StepperValue" and modifies the "IsValidArray" values. Both changes would typically trigger a re-render of the TelerikStepper component.
  • Immediate vs. Asynchronous Updates: Without "Task.Delay", all updates occur synchronously. When you set "StepperValue = index" and then immediately update the "IsValidArray" in the same method without awaiting an asynchronous operation, Blazor tries to batch the UI updates efficiently. This can result in the UI not updating as expected because Blazor may not recognize that a re-render is necessary immediately.
  • Effect of Task.Delay: Adding "await Task.Delay(1);" introduces a small asynchronous delay that forces Blazor to pause, process pending UI updates, and then continue with the rest of the method. This effectively tells Blazor that it needs to perform a state update after the "StepperValue" change and before continuing with further changes to the "IsValidArray". This small delay allows Blazor to manage the DOM updates more predictably, ensuring the UI reflects the state changes correctly.

Regards,
Hristian Stefanov
Progress Telerik

Do you have a stake in the designеr-developer collaboration process? If so, take our survey to share your perspective and become part of this global research. You’ll be among the first to know once the results are out.
-> Start The State of Designer-Developer Collaboration Survey 2024

Felix Bohn
Posted on: 19 Aug 2024 10:47
Sadly, only using the @key parameter does not solve the issue.
It turns out that the Task.Delay(1); seems to solve the Issue somehow.

Is this intended?
ADMIN
Hristian Stefanov
Posted on: 05 Aug 2024 13:59

Hi Felix,

Here is an improved version of the configuration where I added the @key parameter. Using @key ensures that each StepperStep is accurately tracked and updated based on its unique index, which also guarantees correct DOM updates.

<TelerikStepper Linear="true" Value="@StepperValue" ValueChanged="@HandleValueChanged">
    <StepperSteps>
        @for (int i = 0; i < IsValidArray.Length; i++)
        {
            <StepperStep Valid="@IsValidArray[i]" @key="@i"></StepperStep>
        }
    </StepperSteps>
</TelerikStepper>

@code {
    private int StepperValue { get; set; } = 0;

    bool?[] IsValidArray = new bool?[] { null, null, null, null };

    public async Task HandleValueChanged(int index)
    {
        StepperValue = index;

        await Task.Delay(1);

        for (int i = 0; i < IsValidArray.Length; i++)
        {
            IsValidArray[i] = index > i ? true : null;
        }
    }
}

The Stepper seems to work correctly. Thus, I'm marking this item as declined.

Regards,
Hristian Stefanov
Progress Telerik

Do you have a stake in the designеr-developer collaboration process? If so, take our survey to share your perspective and become part of this global research. You’ll be among the first to know once the results are out.
-> Start The State of Designer-Developer Collaboration Survey 2024