Nadeeja Pirisyala
Nadeeja Pirisyala

Reputation: 11

ngFor rendering items on top of each other in resposive carousel

I'm using Angular 11 and https://www.npmjs.com/package/angular-responsive-carousel responsive carousel. The carousel is populated with mat-cards using an array. But when the page loads for the first time all the cards are rendered on top of each other as shown here

But it should look like this

But after the window is resized and taken back to the original size the carousel renders fine. I want to find a way to have the cards rendered right in the first go.

The HTML code looks like this

<carousel [dots]="true" [cellsToShow]=cellsToShow [height]="carouselHeight" [autoplay]="false"
        [autoplayInterval]="2000"
        [borderRadius]="2" [pauseOnHover]="true">
<div class="carousel-cell" *ngFor="let item of cards; index as i; trackBy: fun">
  <mat-card class="example-card mat-elevation-z0">
    <mat-card-header>
      <a mat-card-avatar class="example-header-image" [href]="telegramUrl" target="_blank"</a>
      <mat-card-title><b>Ultime Offerte</b></mat-card-title>
      <mat-card-subtitle><i>Di Offerte Nerd</i></mat-card-subtitle>
    </mat-card-header>
    <br>
    <div class="example-card-image"><img mat-card-image [src]=item[0] alt=""></div>
    <mat-card-content>
      <div [innerHTML]="item[1]"></div>
      <br>
      {{item[2]}} <a href="{{item[3]}}" target="_blank">{{item[3]}}</a>
    </mat-card-content>
  </mat-card>
</div>

The CSS looks like this.

.carousel{
  position: relative;
  z-index: 1;
  padding-left: 10%;
  padding-right: 10%;
}

.carousel-cells{
  height: auto !important;
}

.carousel-cell{
  height: auto !important;
}

.example-card {
  max-width: 70vw;
  text-align: left;
  overflow-wrap: break-word;
  height: auto !important;
  border-style: solid;
  border-width: thin;
}

Upvotes: 1

Views: 499

Answers (2)

Swaroop R M
Swaroop R M

Reputation: 36

It happens because the carousel renders before the data is added to the cards. Since there is no data during carousel rendering, carousel cells don't take the actual width inside the carousel.

There is a simple solution for this. We need to provide the default width for the carousel-cells. It can be done by adding an attribute provided in the package. 'cellWidth'. Refer the below code.

<carousel [cellsToShow]=5 [cellWidth]=250 [arrows]=false>
      <div> Your content </div>
 </carousel>

Since the attribute supports property binding we can try giving width of cells according to the screen size from typeScript file. I've not tried with that but the above code worked for me for laptop screen.

Upvotes: 0

Aram Khachatrian
Aram Khachatrian

Reputation: 399

It's just my guess but try to call cdRef.markForCheck() in ngAfterViewInit() lifecycle hook of the component where you use the carousel:

import { Component, AfterViewInit, ChangeDetectorRef } from '@angular/core';

@Component({
  ...
})
export class MyComponent implements AfterViewInit {
  constructor(private cdRef: ChangeDetectorRef) {}

  ngAfterViewInit(): void {
    this.cdRef.markForCheck();
    // also try this.cdRef.detectChanges(); instead of the above
  }
}

But much better is to trigger change detection right at the point where the data which you feed to the carousel is ready.

Upvotes: 1

Related Questions