Skip to content

AutoSizeVirtualScrollStrategy throws "Cannot read properties of undefined (reading 'size')" when data size decreases #1871

@friendlyAce

Description

@friendlyAce

Description

When using the AutoSizeVirtualScrollStrategy, i am frequently running into this exception, which causes my whole component to break until its re-created:

Uncaught TypeError: Cannot read properties of undefined (reading 'size')
    at _AutoSizeVirtualScrollStrategy.getItemSize (template-experimental-virtual-scrolling.mjs:999:38)
    at _AutoSizeVirtualScrollStrategy.updateElementSize (template-experimental-virtual-scrolling.mjs:990:26)
    at Object.next (template-experimental-virtual-scrolling.mjs:841:14)
    at tap.js:17:71
    at OperatorSubscriber2._this._next (OperatorSubscriber.js:14:9)
    at Subscriber2.next (Subscriber.js:32:12)
    at Subscriber2._next (Subscriber.js:59:22)
    at Subscriber2.next (Subscriber.js:32:12)
    at filter.js:7:68
    at OperatorSubscriber2._this._next (OperatorSubscriber.js:14:9)

The exception, in most cases happens here in autosize-virtual-scroll-strategy.ts#L797.

Unfortunately im not able to share the source code, but my usage is very similar to this:

<div style="height: 300px; overflow: auto; border: 1px solid black;">
    <rx-virtual-scroll-viewport
        autosize
        [appendOnly]="true"
        [tombstoneSize]="25"
        [runwayItems]="5"
        [runwayItemsOpposite]="5"
        [initialScrollIndex]="0"
        (scrolledIndexChange)="scrolledIndex$$.next($event)"
        (viewRange)="currentViewRange$$.next($event)"
    >
        <ng-container
            *rxVirtualFor="
                            let item of data$;
                            trackBy: trackById;
                            let index = index;
                        "
        >
            <div class="row">
                <ng-container
                    *ngTemplateOutlet="
                                    rowTemplate;
                                    context: {
                                        item: item,
                                        index: index,
                                    }
                                "
                ></ng-container>
            </div>
        </ng-container>
    </rx-virtual-scroll-viewport>
</div>

<ng-template #rowTemplate let-item="item" let-index="index">
    <div
        *rxIf="item | isLoadingComplete; suspense: suspenseTemplate"
        style="height: 50px; border-bottom: 1px solid gray;"
        class="item">
        <div class="cell">{{ item.id }}</div>
        <div class="cell">{{ item.value }}</div>
    </div>
</ng-template>

<ng-template #suspenseTemplate>
    <div>Loading...</div>
</ng-template>

This mainly happens when my input data that is passed to rxVirtualFor directive changes.
Especially if the new data is noticeable less than before (e. g. 1000 items before, 9 item now)
The index internally, that causes the error always seems to overshoot by exactly 1.
e. g. here its accessing a non-existent index 9
Image
or 2
Image

Its also interesting that it still renders the items to the dom, but just transforms them way out of the view port
Image

Im also frequently getting this error when using the fixed size scroll strategy

Uncaught TypeError: Cannot set properties of undefined (setting 'position')
    at _FixedSizeVirtualScrollStrategy._setViewPosition (template-experimental-virtual-scrolling.mjs:1792:19)
    at Object.next (template-experimental-virtual-scrolling.mjs:1696:14)
    at tap.js:17:71
    at OperatorSubscriber2._this._next (OperatorSubscriber.js:14:9)
    at Subscriber2.next (Subscriber.js:32:12)
    at Subject.js:41:22
    at errorContext (errorContext.js:23:5)
    at Subject2.next (Subject.js:31:5)
    at onStrategy.ngZone (template-experimental-virtual-scrolling.mjs:2579:32)
    at work (cdk-render-strategies.mjs:188:17)

this in most cases (but not in all) does not occur when wrapping the row template in a DIV instead of using ng-container with an ng template outlet directly in the rx virtual for

Environment

@angular/core: 18
@rx-angular/cdk: 18.0.0
@rx-angular/template 18.0.3

Expected Behavior

The viewport should correctly calculate the item sizes and render the items, without throwing an error.

Actual Behavior

The component that uses the rx virtual scrolling crashes with the above error, indicating that the size property is being accessed on an undefined object.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions