title: virtual scroll for angular not adding data to list
body: <p>I've tried implementing infinite virtual scroll on Angular 7 project with Hasura's GraphQL backend. </p>
  
  <p>I'm unable to figure out why the new data is not added and why there are multiple API requests when I scroll.</p>
  
  <p><strong>Here's the component, feed.component.ts</strong></p>
  
  <pre><code>import { Component, OnInit, ViewChild } from '@angular/core';
  import { IdeaService } from '@app/core/idea/idea.service';
  import { MatDialog } from '@angular/material';
  import { IdeaCardComponent } from '@app/shared/idea-card/idea-card.component';
  import { CdkVirtualScrollViewport } from '@angular/cdk/scrolling';
  import { Observable, BehaviorSubject } from 'rxjs';
  import { map, tap, merge, throttleTime, scan, mergeMap } from 'rxjs/operators';
  
  const batchSize = 10;
  
  @Component({
    selector: 'app-idea-feed',
    templateUrl: './idea-feed.component.html',
    styleUrls: ['./idea-feed.component.scss']
  })
  export class IdeaFeedComponent implements OnInit {
    @ViewChild(CdkVirtualScrollViewport)
    viewport: CdkVirtualScrollViewport;
  
    isEndOfTheList = false;
    offset = new BehaviorSubject(null);
    infinite: Observable&lt;any[]&gt;;
  
    length: number;
    ideaList: any[] = [];
    pageIndex = 0;
    pageEvent: any;
    constructor(private ideaService: IdeaService, public dialog: MatDialog) {
      const batchMap = this.offset.pipe(
        throttleTime(500),
        mergeMap(n =&gt; this.getIdeasFromServer(n)),
        scan((acc, batch) =&gt; {
          return { ...acc, ...batch };
        }, {})
      );
  
      this.infinite = batchMap.pipe(map(v =&gt; Object.values(v)));
      console.log(this.infinite);
    }
  
    nextBatch(e: any, offset: any) {
      if (this.isEndOfTheList) {
        return;
      }
  
      const end = this.viewport.getRenderedRange().end;
      const total = this.viewport.getDataLength();
  
      if (end === total) {
        this.offset.next(offset);
      }
    }
  
    trackByIndex(i: any) {
      return i;
    }
  
  
    ngOnInit() {
      this.ideaService.getTotalIdeaCount().subscribe(data =&gt; {
        this.length = data.data.ideas_aggregate.aggregate.count;
      });
    }
  
    getIdeasFromServer(pageIndex: any) {
      console.log(this.ideaList, this.pageIndex);
  
      return this.ideaService.getNIdeas(batchSize, pageIndex).pipe(
        map((data: any) =&gt; {
          this.pageIndex += 10;
          data.data.ideas.forEach((idea: any) =&gt; {
            this.ideaList.push(idea);
          });
          this.ideaList = data.data.ideas;
          return data.data.ideas;
        })
      );
    }
  }
  
  </code></pre>
  
  <p><strong>Here's the HTML, feed.component.html</strong></p>
  
  <pre><code>&lt;div *ngIf="(infinite | async) as ideaList" class="ideafeed-background"&gt;
    &lt;cdk-virtual-scroll-viewport itemSize="100" scrolledIndexChange)="nextBatch($event, pageIndex)"&gt;
          &lt;mat-card
            class="idea-card"
            *cdkVirtualFor="let item of ideaList; let i = index; trackBy: trackByIdx"&gt;
       {{ item.name }}
      &lt;/mat-card&gt;
    &lt;/cdk-virtual-scroll-viewport&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>I'm not sure what I'm doing wrong. I've followed <a href="https://www.youtube.com/watch?v=Ppl64MY6FFc" rel="nofollow noreferrer">this</a> tutorial </p>