I'm building a vertically scrolling calendar. I'm getting the initial days to load, but when new days are added to the list, they aren't being rendered.
<cdk-virtual-scroll-viewport
class="demo-viewport"
[itemSize]="100"
(onContentScrolled)="handleScrollChange($event)"
>
<calendar-day
*cdkVirtualFor="let day of days; trackBy: trackByFn"
[day]="day"
></calendar-day>
</cdk-virtual-scroll-viewport>
<button (click)="goToToday()">go</button>
I have a service with a BehaviorSubject
updating the days. I know the list of days is being updated, but the change doesn't seem to be detected.
ngOnInit() {
this._daysService.days$.subscribe(days => {
this.days = days;
})
this.watchScroll();
this.handleScrollingUp();
this.handleScrollingDown();
}
For more info, the StackBlitz repo is public https://stackblitz.com/edit/material-infinite-calendar
I figured this out.
Originally, I was adding new days by grabbing the current value like this
let items = this.items$.value;
items.push(newItem);
this.items$.next(items)
Apparently, this is actually a mutation of the value of the BehaviorSubject
's value, therefore not creating a new array to return and not triggering change detection.
I changed it to
let items = [...this.items$.value];
items.push(newItem);
this.items$.next(items)
and all is good.
So, although the answers here are correct in that I was mutating the original array, the information I needed was calling next()
with a mutated version BehaviorSubject
's current value does not emit a new array. An emit
event does not guarantee immutability.