components icon indicating copy to clipboard operation
components copied to clipboard

virtual-scroll: attempted to use view after destroyed errors

Open mmalerba opened this issue 6 years ago • 16 comments

These occasionally pop up, need to investigate root cause

mmalerba avatar May 11 '18 15:05 mmalerba

I am getting these a lot!!!! As a temporary workaround, I added a simple check to see if the view is destroyed in CdkVirtualForOf._updateContext. Although this makes my browser console window less red, I imagine there is an underlying problem somewhere else.

Here is my patch:

CdkVirtualForOf.prototype['_updateContext'] = function (this: any) { const count = this._data.length; let i = this._viewContainerRef.length; while (i--) { let view = this._viewContainerRef.get(i) as EmbeddedViewRef<CdkVirtualForOfContext<any>>; if (!view.destroyed) { view.context.index = this._renderedRange.start + i; view.context.count = count; this._updateComputedContextProperties(view.context); view.detectChanges(); } } }

grant77 avatar Aug 25 '18 21:08 grant77

@grant77 are you seeing this with autosize strategy or fixed size strategy? so far I've only seen it with autosize

mmalerba avatar Aug 26 '18 00:08 mmalerba

Fixed size strategy.

grant77 avatar Aug 26 '18 01:08 grant77

If you're able to create a reproduction I'd love to see it, would probably be easier to debug with the fixed size strategy

mmalerba avatar Aug 26 '18 01:08 mmalerba

I'll try to put something together tomorrow.

grant77 avatar Aug 26 '18 01:08 grant77

Here you go:

https://stackblitz.com/edit/angular-material2-issue-huoqn3

Note: My VirtualDataSource is a work in progress. Basically, I am trying to pull data in chunks from my API as they scroll. You should get a plethora of errors as you scroll. The error is:

** ERROR Error: ViewDestroyedError: Attempt to use a destroyed view: detectChanges

grant77 avatar Aug 26 '18 22:08 grant77

@grant77 Thanks for the repro. After some experimentation, it looks like the errors are happening when the length of the data shrinks to be smaller than what the user is currently viewing. I'll look into how to fix it. Aside from this bug there's probably something strange going on with your DataSource that you may want to look into. I can't tell from looking at it why the data length would be constantly changing

mmalerba avatar Aug 29 '18 22:08 mmalerba

Your welcome. Thanks for fixing #12869 so quick. I have forked the demo above and added three things:

  • The fix you gave me from #12869 regarding viewChange inside zone. I removed the setInterval hack.
  • Uncommented the patch for CdkVirtualForOf._updateContext that suppresses the errors so you can see what I am logging.
  • tap(data => console.log(data.length)) as last rxjs thing in DataSource to write the data length.

https://stackblitz.com/edit/angular-material2-issue-eeiups

I don't see it logging anything but 10000.

grant77 avatar Aug 30 '18 00:08 grant77

Hmm, ok maybe I'm wrong then. Your data source must be doing something interesting that I'm not capturing.

I tried to make a simpler DataSource for the sake of debugging: https://stackblitz.com/edit/angular-material2-issue-nxvupb?file=app/app.component.ts I noticed that this one is fine if I leave the length constant, but if I uncomment the line randomizing the length and scroll to the end of the list I start to get the same kind of errors. I assumed yours must be having similar issues, but it sounds like maybe something else is going on

mmalerba avatar Aug 30 '18 16:08 mmalerba

This is mind-boggling. I modified your demo a little bit, and now I can get the errors again, but not as easily as I could with my demo. You have to jerk the scrollbar back and forth. Here you go:

https://stackblitz.com/edit/angular-material2-issue-ijb5fc

grant77 avatar Aug 30 '18 22:08 grant77

If it's helpful, I have another test case. Steps:

  1. Open Chrome mobile simulator (not necessary, but makes the issue more consistently reproducible for me)

  2. Navigate to https://websign.cyph.wang/simple-master#account

  3. Login in with username elon and password hunter2

  4. Quickly scroll up and down a bunch of times

This is what the relevant code looks like:

<cdk-virtual-scroll-viewport
	fxFlexFill
	[itemSize]='86 + ((envService.isMobile | async) ? 8 : 16)'
	class='contact-list'
>
	<ng-container *cdkVirtualFor='
		let item of filteredContactList; trackBy: trackByUser
	'>
		<ng-container *ngTemplateOutlet='listItem; context: {
			item: item
		}'></ng-container>
	</ng-container>
</cdk-virtual-scroll-viewport>

buu700 avatar Sep 01 '18 00:09 buu700

Also seeing this issue and it appears quite a lot when the collection is updated. Can't seem to figure out exactly what's happening, but I can trigger it consistently if I filter the collection by certain items. Although once it's been triggered the first time, it can happen randomly (and sometimes even in an infinite loop).

jinder avatar Oct 18 '18 15:10 jinder

I had similar issues but managed to completely overcome it by fiddling with the templateCacheSize:

<div *cdkVirtualFor="let item of items; templateCacheSize: 100" class="example-item">{{item}}</div>

See documentation at https://material.angular.io/cdk/scrolling/overview

Kim-Andersen avatar Oct 31 '18 09:10 Kim-Andersen

@Kim-Andersen thanks for the tip - seems to solve the issue for me!

jinder avatar Oct 31 '18 10:10 jinder

I've just noticed in our code that the trackBy code was using an incorrect function signature (it was comparing on the first parameter which is index and not the item in the list). Since fixing this, I'm not seeing the issue so far (even without the templateCacheSize change).

jinder avatar Nov 07 '18 17:11 jinder

@Kim-Andersen - Thanks Kim. Your solution worked for me. I know in recent version of material they fixed this issue but I really dont have scope to upgrade the version as my application is live and there is no plan to invest on the upgrade task

surajpatnaik1986 avatar Jul 26 '22 01:07 surajpatnaik1986