CdkVirtualScrollViewport has already been connected (ERROR)

I'm currently working on a project that requires displaying more than 1000 records. I thought about using the virtual scroll feature from Angular Material CDK, but I encountered an error:

Error: CdkVirtualScrollViewport is already attached.
.

Template

<div class="news-feeds-wrapper">
  <div class="news-feeds-icon" *ngIf="configService.config.showNewsFeeds" (click)="toggleNewsFeeds()">
    <span *ngIf="platform.EDGE || platform.TRIDENT" class="icon-hype-notification_important"></span>
    <mat-icon *ngIf="!platform.EDGE && !platform.TRIDENT">notification_important</mat-icon>
  </div>
  <cdk-virtual-scroll-viewport itemSize="50">
    <div class="news-feeds-list" [ngClass]="{'open': newsFeedOpen}">
      <div *cdkVirtualFor="let group of newsFeeds">
        <div class="time" *ngIf="group.values.length > 0">{{group.type}}</div>
        <div class="news-feed" *cdkVirtualFor="let item of group.values | async">
          <div class="header">
            <i [ngSwitch]="item.action_type">
              <mat-icon *ngSwitchCase="'Task Assignment'">swap_horiz</mat-icon>
              <mat-icon *ngSwitchCase="'User Mention'">chat</mat-icon>
              <mat-icon *ngSwitchCase="'Task Deleted'">no_sim</mat-icon>
            </i>
            <span>{{item.action_type}}</span>
            <mat-icon class="deleted-news-feed" (click)="deletedNewsFeeds(group.values, item)">clear</mat-icon>
          </div>
          <div class="news-feed-content">
            <div class="info-content">
              <p class="project">{{item.project}}</p>
              <p class="taskboard">{{item.task_board}}</p>
              <p class="board-item">{{item.task_board_item}}</p>
            </div>
            <div class="avatar">
            </div>
          </div>
        </div>
      </div>
    </div>
  </cdk-virtual-scroll-viewport>
</div>

Component

@Component({
  selector: 'news-feeds',
  templateUrl: '../templates/news-feed.component.html',
  styleUrls: ['../../assets/scss/news-feeds.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class NewsFeedsComponent implements OnInit {
  public newsFeedOpen = false;
  public newsFeeds: Array<any> = [];

  @HostListener('document:click', ['$event'])
  closeNewsFeeds(event) {
    if (this.newsFeedOpen && event.target.localName != 'mat-icon') {
      this.newsFeedOpen = false;
    }
  }

  constructor(public platform: Platform, public configService: HypeConfigService, private cd: ChangeDetectorRef, private log: LoggingService, private backlogService: BacklogTaskService) {
    //
  }

  ngOnInit() {
    //
  }

  toggleNewsFeeds() {
    this.backlogService.getNewsFeeds().subscribe(
      (response) => {
        this.newsFeedOpen = !this.newsFeedOpen;
        this.newsFeeds = response;
        this.cd.markForCheck();
      },
      (error) => {
        this.log.error(`Error loading the news feeds: ${error}`);
      }
    );
  }

  deletedNewsFeeds(group: Array<any>, newsFeed: any) {
    const index = group.findIndex((i) => i.id === newsFeed.id);
    group.splice(index, 1);
  }
}

It seems to be indicating that CdkVirtualScrollViewport is already attached, even though it's not used elsewhere in my application. Here is the StackBlitz link

Answer №1

The problem arises from utilizing *cdkVirtualFor twice nested within each other... To fix this issue, I implemented two changes;

  1. app.component.html: Replaced *cdkVirtualFor with *ngFor, like so
    • <div class="news-feed" *ngFor="let item of group.values">
      instead of
    • <div class="news-feed" *cdkVirtualFor="let item of group.values">
  2. app.component.css: Included
    cdk-virtual-scroll-viewport { height:400px; }
    due to the default height being zero

Changes in HTML & CSS are shown in the code snippet below

cdk-virtual-scroll-viewport {
  height: 400px;
}
<div class="news-feeds-wrapper">
  <div class="news-feeds-list open">
    <cdk-virtual-scroll-viewport itemSize="50" class="example-viewport">
      <div *cdkVirtualFor="let group of newsfeeds">
        <div class="time">{{group.type}}</div>
        <div class="news-feed" *ngFor="let item of group.values">
          <div class="header">
            <span>{{item.action_type}}</span>
            <mat-icon class="deleted-news-feed">clear</mat-icon>
          </div>
          <div class="news-feed-content">
            <div class="info-content">
              <p class="project">{{item.project}}</p>
              <p class="taskboard">{{item.task_board}}</p>
              <p class="board-item">{{item.task_board_item}}</p>
            </div>
            <div class="avatar">
            </div>
          </div>
        </div>
      </div>
    </cdk-virtual-scroll-viewport>
  </div>
</div>

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

Why does the ReactJS MaterialUI Modal fail to update properly?

Recently, I encountered a curious issue with my Modal component: https://i.stack.imgur.com/dkj4Q.png When I open the dropdown and select a field, it updates the state of the Object but fails to render it in the UI. Strangely, if I perform the same action ...

The data in the array JSON is undefined, resulting in the inability to read property 'x'

Having issues with my code snippet: <div class="photo-gallery1" *ngIf="plans.attachments.length > 0"> ... </div> Here is the JSON data for 'plans': https://i.sstatic.net/zqsMg.png I encountered an error in my code: https://i.s ...

Sending a Thunk to the store using Typescript

Within my primary store.ts file, the following code is present: const store = createStore( rootReducer, composeWithDevTools(applyMiddleware(thunk)) ); store.dispatch(fetchUser()); Upon initial rendering, an action is dispatched to fetchUser in ord ...

Removing a row from a FormArray within a FormGroup is not the appropriate method for managing input fields within a MatTable

I am encountering an issue with my MatTable, which is formed from a formarray. When I delete a row, the values in the input fields of my table are not updating as expected. However, the data in the object reflects the correct changes after deleting the r ...

Configuration error with MultiCapabilities

Encountering an issue while utilizing multiCapabilities with two web browsers (Firefox and Chrome). Below is a snippet from my configuration: exports.config = { allScriptsTimeout: 11000, seleniumAddress: 'http://localhost:4444/wd/hub', b ...

Guide to implementing lazy loading and sorting in p-Table with Angular2

I recently implemented lazy loading in my application and now I am having trouble with sorting items. When lazy loading is disabled, the sorting feature works perfectly fine. However, I need help to make both lazy loading and sorting work simultaneously. C ...

Utilizing a mutual RxJS subject for seamless two-way data binding in Angular 2

I have a unique service dedicated to managing app configurations class Configuration { get setting() { return dataStore.fetchSetting(); } set setting(value) { dataStore.saveSetting(value); } } This configuration is linked to components t ...

Autocomplete feature shows usernames while storing corresponding user IDs

I am looking to enhance the autocomplete functionality in my application while also ensuring that the selected user ID is stored in the database. Specifically, I want the autocomplete feature to display user names for selection purposes, but instead of re ...

Deploy a multilingual Angular application on Firebase with the help of functions

My current challenge involves correctly managing requests for a localized angular app hosted on Firebase. The objective is to load the appropriate app bundle based on: 1) A cookie named locale. 2) The accept-language header. 3) Defaulting to en-us if other ...

Using TypeScript, we can assign a JSON object to an extended class by leveraging the

Task was to include an additional property. I modified a current class by adding a new property, but when I assign a JSON object from the database, the newly added property disappears. Is there a way to correctly assign a JSON object to a TypeScript class ...

Troubles encountered while attempting to properly mock a module in Jest

I've been experimenting with mocking a module, specifically S3 from aws-sdk. The approach that seemed to work for me was as follows: jest.mock('aws-sdk', () => { return { S3: () => ({ putObject: jest.fn() }) }; }); ...

An issue with the Pipe searchByType is resulting in an error stating that the property 'type' is not found on the type 'unknown'

I keep encountering a range of errors like roperty does not exist on type 'unknown' after running the command ionic build --prod --release src/app/pages/top-media/top-media.page.ts:18:16 18 templateUrl: './top-media.page.html', ...

Angular: Card disabled post-click

I am displaying three cards <div *ngFor="let catalog of catalogs;let i=index" (click)="goToProducts(catalog)"> <div> <div class="name-position text {{catalog.classe}}" style="font-size: 21px;"> ...

Tips for designing a personalized payment page in PayPal for flexible one-time and subscription-based payments

How can I display a PayPal checkout page with custom fields such as tax and total amount when a user makes a payment for a custom amount? Can multiple fields like sales tax and total amount be added? In addition to that, our web application already has Pa ...

How come Angular8's routerLinkActive is applying the active class to both the Home link and other links in the navigation bar simultaneously?

Currently, I am facing an issue with routing in my project where the home tab remains active even when I click on other tabs. I have tried adding routerLinkActiveOption as a solution, but it doesn't seem to be working for me. <ul class="nav nav-ta ...

Limit the values in the array to only match the keys defined in the interface

I'm trying to restrict an array's elements to specific keys of an interface: interface Foo { bar: string; baz: number; foo: string; } type SelectedKeysArray<T, K extends keyof T> = Pick<T, K>[]; const selectedKeys: SelectedKey ...

What is the best way to test the SSM getParameter function using Jasmine?

Is there a way to effectively test this? const ssmParameterData = await ssm.getParameter(params, async (error, data) => { if (error) throw error; return data; }).promise(); I have attempted mocking the method by doing: spyOn(ssm, 'getParameter& ...

Update angular2 to the latest 2.4.1 release, moving up from version 2.1.1

My goal is to upgrade my Angular2 version from 2.1.1 to 2.4.1 I started with this seed project. This was my original package.json content: { "name": "angular2-webpack-starter", "version": "5.1.1", "description": "An Angular 2 Webpack Starter ki ...

Splitting an array of objects into multiple arrays of objects based on their properties

At the moment, I am working with an array that contains multiple objects const bankData = [ { "bank": "Chase", "monthEndBalance": "72,175.88", "bankStatementDate": "2020/10/31&quo ...

What is the correct way to use forwardRef in a dynamic import in Next.js?

I've been trying to incorporate the forwardRef in my code, but I'm facing some difficulties. Can anyone help me out with this? I'm encountering the following errors: Property 'forwardedRef' does not exist on type '{}'. ...