Angular virtual scrolling not populating the list with data

I have encountered a challenge while trying to implement infinite virtual scroll on an Angular 7 project with a GraphQL backend from Hasura.

I am puzzled by the fact that the new data is not being added and there are multiple API requests being made when I scroll.

Below is the code snippet for the feed.component.ts component:

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<any[]>;

  length: number;
  ideaList: any[] = [];
  pageIndex = 0;
  pageEvent: any;
  constructor(private ideaService: IdeaService, public dialog: MatDialog) {
    const batchMap = this.offset.pipe(
      throttleTime(500),
      mergeMap(n => this.getIdeasFromServer(n)),
      scan((acc, batch) => {
        return { ...acc, ...batch };
      }, {})
    );

    this.infinite = batchMap.pipe(map(v => 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 => {
      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) => {
        this.pageIndex += 10;
        data.data.ideas.forEach((idea: any) => {
          this.ideaList.push(idea);
        });
        this.ideaList = data.data.ideas;
        return data.data.ideas;
      })
    );
  }
}

Here's the HTML code snippet for feed.component.html:

<div *ngIf="(infinite | async) as ideaList" class="ideafeed-background">
  <cdk-virtual-scroll-viewport itemSize="100" scrolledIndexChange)="nextBatch($event, pageIndex)">
        <mat-card
          class="idea-card"
          *cdkVirtualFor="let item of ideaList; let i = index; trackBy: trackByIdx">
     {{ item.name }}
    </mat-card>
  </cdk-virtual-scroll-viewport>
</div>

I am unsure of what mistake I might be making. I have followed a tutorial which can be found here.

Answer №1

Encountered a similar issue and resolved it by modifying the push method to:

this.updatedIdeaList = [...this.updatedIdeaList, newIdea];

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Is it necessary to ensure application readiness before proceeding with unit testing exports?

I've been facing a challenge while trying to utilize Jest for unit testing an express API that I've developed. The issue arises when the database needs to be ready before running the test, which doesn't seem to happen seamlessly. In my serve ...

Deactivate multiple textareas within a loop by utilizing JQuery/Typescript and KnockoutJS

I am working on a for loop that generates a series of textareas with unique ids using KO data-binding, but they all share the same name. My goal is to utilize Jquery to determine if all the textareas in the list are empty. If they are, I want to disable al ...

Creating a method that can adopt the return type of the nested function?

I have a function that takes in a callback and returns the value obtained using the useSelector hook from the react-redux library. Is there a way to utilize the return type of useSelector within my wrapper function? import { shallowEqual, useSelector } f ...

Angular is throwing an error stating that it is unable to access the 'name' property of an undefined object

While working on my Angular application, I encountered the following error message: " Cannot read property 'name' of undefined" https://i.stack.imgur.com/O3vlh.png I've been searching through my code but am unable to pinpoint the issue. T ...

Please ensure to close the dropdown menu once the function has been called

I'm encountering an issue with a dropdown menu. When I expand the dropdown menu, everything works as expected. However, is it possible to disable the first search button and the txtSearch input field (referring to the class "glyphicon glyphicon-search ...

Working with intricately structured objects using TypeScript

Trying to utilize VS Code for assistance when typing an object with predefined types. An example of a dish object could be: { "id": "dish01", "title": "SALMON CRUNCH", "price": 120, ...

Passing NextJS props as undefined can lead to unexpected behavior and

Struggling with dynamically passing props to output different photo galleries on various pages. One of the three props works fine, while the others are undefined and trigger a warning about an array with more than one element being passed to a title elemen ...

Is there a way to import a module generated by typescript using its name directly in JavaScript?

I am trying to bring a function from a typescript-generated module into the global namespace of JavaScript. The typescript module I have is called foo.ts: export const fooFn = (): string => { return "hello"; }; Below is the structure of my HTML file ...

Transferring information from child to parent class in TypeScript

I have a scenario where I have two classes (Model). Can I access properties defined in the child class from the parent class? Parent Class: class Model{ constructor() { //I need the table name here. which is defined in child. } publ ...

Error TS2694 is being caused by Electron Typescript Material-UI withStyles because the namespace "".../node_modules/csstype/index"" does not have an exported member called 'FontFace'

While I am experienced with Material-UI, I am relatively new to Electron and using React, TypeScript, and Material-UI together. Recently, I encountered an error while attempting to create an electron boilerplate code for future project initialization. Init ...

Merge the values of checkboxes into a single variable

How can I gather all the checkbox values from my list and combine them into a single variable? This is the structure of my HTML: <div class="card" *ngFor="let event of testcases" > <input class="form-check-input" ...

Angular 2 ngIf displaying briefly before disappearing

Encountering a strange issue with an Angular 2 ngIf statement where it appears on the page for a brief moment and then disappears. The content is visible, but it doesn't remain on the page. I suspect it might be related to some asynchronous behavior. ...

One or multiple web browsers set in the Browserslist of the project

I have recently started working with the Ionic framework and encountered some warnings while setting up my application. Can anyone help me with a solution? [ng] When starting the Ionic application, I received the following warnings: [ng] One or more browse ...

Tips for retrieving information from a Vuetify modal window

Is it possible to retrieve data from a dialog in the VueJS Vuetify framework? Specifically, how can I access the username or password entered in the NewUserPopup.vue dialog from app.vue? App.vue = main template NewUserPopup.vue = Dialog template imported ...

Typescript does not process and compile files located within a specified directory

Recently, I embarked on a small TypeScript project and took the time to create the tsconfig.json configuration file. { "compilerOptions": { "target": "es5", "module": "commonjs", "sourceMap": true }, "files": [ "./typings/index.d.ts" ...

Encountered an unexpected import token in Angular2 (SystemJS)

i am trying to find a solution for this issue in my Angular2 project. I encountered an error and need assistance: `"(SystemJS) Unexpected token import SyntaxError: Unexpected token import at Object.eval (http://....../app.module.js:14:25) at eval (h ...

Is it possible to identify unauthorized utilization of web APIs within TypeScript?

Recently, I encountered an issue while using the URLSearchParams.size in my code. To my surprise, it didn't work on Safari as expected. Checking MDN's browser compatibility table revealed that Safari version 16.6 does not support this feature, un ...

How to use Angular 2 to communicate with JavaScript API whenever the router switches to

I am currently working on an Angular2 component that has a template which relies on JavaScript calls to load various components such as Facebook, Google Maps, and custom scripts. The necessary scripts are already loaded in the index.html file, so all I ne ...

Ways to specify the T (Generic type) associated with the class

I am working with a class that uses a generic type like this: SomeGenericClass<T>{ constructor(){ } } Within some of the functions, I log messages and want to refer to the current type T of the generic class in my logs. I have attempted t ...

The condition will be false if a number is present, even if it is zero

I am facing an issue with a class containing an optional field called startDateHour: export class Test { startDateHour?: number; // more fields, constructor etc. } I need to perform an action only if the startDateHour exists: if (test.startDateHour ...