Having the Angular directive ngFor applied to a Bootstrap carousel item that is set

component.html

<section *ngFor="let project of projectList" class="child p-5">
    <div class="first">
        <h1>{{ project.title }}</h1>
        <p><strong>{{ project.description }}</strong></p>
    </div>


    <div id="car_{{ project.title}}" class="carousel slide second" data-ride="carousel">
        <div class="carousel-inner">
            <div *ngFor="let file of mediaList">
                <div *ngIf="file.postId == project._id ">
                    <div class="carousel-item active">
                        <img src="{{ url+file.path }}" class="d-block mx-auto"
                            style="height: -webkit-fill-available;">
                    </div>
                </div>
            </div>
        </div>
        <a class="carousel-control-prev" href="#car_{{ project.title}}" role="button" data-slide="prev">
            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
            <span class="sr-only">Previous</span>
        </a>
        <a class="carousel-control-next" href="#car_{{ project.title}}" role="button" data-slide="next">
            <span class="carousel-control-next-icon" aria-hidden="true"></span>
            <span class="sr-only">Next</span>
        </a>
    </div>
</section>

component.ts

ngOnInit() {
this.url = environment.backendBaseUrl;
this.posts.getPost().subscribe(
  res => {
    this.projectList = res['posts'];
    console.log(res['posts']);
  },
  err => {
    console.log(err);

  });

this.media.getMedia().subscribe(
  res => {
    this.mediaList = res['mediaFiles'];
    console.log(res['mediaFiles']);
  },
  err => {
    console.log(err);

  });
}

I am struggling with ensuring the carousel item only has the 'active' class applied once. It seems impossible to achieve this using the ngFor index as it won't match either beginning or end:

0: {_id: "5dd78c7ff21808b10c9273dd", title: "SingleImage", description: "single image↵Nam quis tortor nec ligula auctor rut…at tellus vitae maximus. Donec in efficitur odio."}
1: {_id: "5dd78cf3f21808b10c9273df", title: "MultipleImages", description: "Multiple↵Nam quis tortor nec ligula auctor rutrum.…at tellus vitae maximus. Donec in efficitur odio."}
2: {_id: "5dd78ee4cbf2ecadd8e2ac53", title: "Mixed", description: "Mixed↵Nam quis tortor nec ligula auctor rutrum. Cu…at tellus vitae maximus. Donec in efficitur odio."}

0: {_id: "5dd78c7ff21808b10c9273de", path: "uploads\admin\1574407295057.png", type: "image/png", postId: "5dd78c7ff21808b10c9273dd", __v: 0}
1: {_id: "5dd78cf3f21808b10c9273e0", path: "uploads\admin\1574407411823.png", type: "image/png", postId: "5dd78cf3f21808b10c9273df", __v: 0}
2: {_id: "5dd78cf3f21808b10c9273e1", path: "uploads\admin\1574407411821.png", type: "image/png", postId: "5dd78cf3f21808b10c9273df", __v: 0}
3: {_id: "5dd78ee4cbf2ecadd8e2ac54", path: "uploads\admin\1574407908979.png", type: "image/png", postId: "5dd78ee4cbf2ecadd8e2ac53", __v: 0}
4: {_id: "5dd78ee5cbf2ecadd8e2ac55", path: "uploads\admin\1574407908975.png", type: "image/png", postId: "5dd78ee4cbf2ecadd8e2ac53", __v: 0}
5: {_id: "5dd78ee5cbf2ecadd8e2ac56", path: "uploads\admin\1574407908967.mp4.gif", type: "video/mp4", postId: "5dd78ee4cbf2ecadd8e2ac53", __v: 0}
length: 6

This arrangement causes the items to stack on top of each other rather than sliding properly... I don't believe there is a straightforward way to assign a boolean inside the ngFor loop to avoid adding the 'active' class multiple times.

Answer №1

JSON data originates from 2 different tables, and their connection is through the postID field.

To solve this issue, a for loop within a function was utilized to iterate over a 2D array, allowing each element to be accessed individually in order to retrieve the first index in the HTML:

this.media.getMedia().subscribe(
        res => {
            this.mediaList = res['mediaFiles'];
            this.checkId(this.projectList, this.mediaList);
            //console.log(res['mediaFiles']);
        },
        err => {
            console.log(err);

        }
    );
}

public checkId(proj: any, medi: any) {
    var fileList: any[][] = [];     
    var idx: number = 0;

    for (let x = 0; x < proj.length; x++) {
        for (let y = 0; y < medi.length; y++) {
            //console.log(x,y)
            //console.log(medi[y])
            if(y == 0){
                fileList[x] = []
                idx = 0
            }
            if(medi[y].postId == proj[x]._id) {
                fileList[x][idx] = medi[y]
                idx++
                //console.log("idx: "+idx)
            }
        }
    }
    this.filesList = fileList;
    console.log("fileList: ",this.filesList);
}

RESULT:

fileList:  (4) [Array(1), Array(2), Array(3), Array(2)]

The corresponding HTML code now appears as follows:

<section *ngFor="let project of projectList; index as idx" class="child p-5">
    <div class="first">
        <h1>{{ project.title }}</h1>
        <p><strong>{{ project.description }}</strong></p>
    </div>


    <div id="car_{{ idx }}" class="carousel slide second pb-5" data-ride="true" data-wrap="false">
        <ol class="carousel-indicators mb-5 pb-5">
            <li *ngFor="let file of filesList[idx]; index as mdx" [ngClass]="{'active': mdx == 0}"
            [attr.data-target]="'#car_'+ idx" [attr.data-slide-to]="mdx"></li>
        </ol>
        <div class="carousel-inner">
            <div *ngFor="let file of filesList[idx]; index as mdx"
                [ngClass]="{'carousel-item': file.postId == project._id, 'active': mdx == 0}" data-interval="0">
                <img src="{{ url+file.path }}" *ngIf="file.type.includes('image');else videoblock"
                    class="d-block mx-auto" style="max-height: 75vh;max-width: 90vw;min-height: 50vh;">
                <ng-template #videoblock>
                    <video class="d-block mx-auto embed-responsive-item" controls
                        style="max-height: 75vh;max-width: 90vw;min-height: 50vh;">
                        <source src="{{ url+file.path }}" type="{{file.type}}">
                        Your browser does not support the video tag.
                    </video>
                </ng-template>
            </div>
        </div>
        <a class="carousel-control-prev" href="#car_{{ idx }}" role="button" data-slide="prev">
            <span class="carousel-control-prev-icon" aria-hidden="true"></span>
            <span class="sr-only">Previous</span>
        </a>
        <a class="carousel-control-next" href="#car_{{ idx }}" role="button" data-slide="next">
            <span class="carousel-control-next-icon" aria-hidden="true"></span>
            <span class="sr-only">Next</span>
        </a>
    </div>
</section>

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

Storing Global Types in Angular: A Better Approach

Imagine I possess certain universally applicable enums, interfaces, or extensive classes. For example: export interface LogMessage { code: number; message: string; } Where would be the optimal location to store them? What is considered the best pr ...

ReactJS Tutorial: Simple Guide to Updating Array State Data

const [rowData, setRowData] = useState([]); const old = {id: 'stud1', name: 'jake', room: '2'}; const newData = {name: 'jake', room: '3A'}; useEffect(() => { let ignore = false; ...

Retrieving specific properties from a JSON object and logging them

I am attempting to access JSON Object properties directly and log them using the following function : loadProcesses(filter?){ this._postService.getAllProcess(filter) .subscribe( res=> { this.processListe = res; // console.log(this.p ...

Obtain the Accurate Error Response when Posting in Angular 5

My controller has validation in C# as shown below: if (user == null) { ModelState.AddModelError(string.Empty, "Invalid login attempt."); return BadRequest(ModelState); } When I try ...

Using AsyncPipe within an ngFor loop to display items

What is the best practice for using an AsyncPipe within an ngFor loop to handle asynchronous calls for items in a list? Scenario: Imagine I have an Order object with Products, and I need to display each product's manufacturer. However, the manufactur ...

How do you implement forwardRef in a React Component?

Need some assistance please! I am working on creating a component within React and I would like to enhance its accessibility by using forwardRef. Specifically, I am developing a button and utilizing the button's properties along with additional featur ...

What do you think about gulp-typescript and the latest @types typings for TypeScript?

I've added @types/jasmine as a development dependency. This is my gulp task for compiling TypeScript: gulp.task('compile:tests', ['compile:typescript', 'clean:tests'], function () { var project = ts.createProject(&a ...

Define a distinct routing parameter that can be accessed through the ActivatedRoute instance

While working on setting up a router in my application, I encountered the need to define a query parameter that must be retrievable through the ActivatedRoute for compatibility reasons. Recently, I had to create some new sub-routes that do not follow the s ...

The error message "Subscription is not a valid function" is displayed

I'm attempting to subscribe to an observable from a service. The code builds successfully, but I encounter the error "this.service.getBanners(...).subscribe is not a function" when I try to view it in the browser. Service: import { Injectable } from ...

Learn the art of generating multiple dynamic functions with return values and executing them concurrently

I am currently working on a project where I need to dynamically create multiple functions and run them in parallel. My starting point is an array that contains several strings, each of which will be used as input for the functions. The number of functions ...

Unique validation for matching passwords in Angular applications

Looking to incorporate a registration form into my angular/ionic app. The form consists of 6 fields within a formGroup (username, first name, last name, password, confirm password, gender). I am seeking to validate the data on the client side using Angular ...

Angular 5 navigation halted due to guard returning Observable signal

I am managing three routes, with one of them being secured by a guard app.routing-module.ts import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { LoginComponent } from './modul ...

ngx-slick-carousel: a carousel that loops infinitely and adjusts responsively

I have implemented ngx-slick-carousel to showcase YouTube videos in my project. However, I am facing two main issues. Firstly, the carousel is not infinite, and when the last video is reached, there appears to be white spaces before it loops back to the fi ...

Using keyof to access static properties within TypeScript classes

While experimenting with this TypeScript playground code sample, I encountered an issue with defining the greeterBuilderName variable. How can I specify that I want properties of the Greeter function itself (such as prototype, warm_greeter, etc.) when keyo ...

What is the best way to calculate the average price?

Looking for help to calculate the average price of products with the available option "no" in a 2D array. Can anyone assist with this? public class Test { public static void main(String[] args) { double total = 0; Products[][] names = ...

Is there a way to switch the series of an apex chart from one component, even if the chart itself is located in a separate

Currently, I am working with Apexchart and facing a challenge with 2 components. The apex chart resides in the second component, and I aim to trigger a function in the first component to toggle or deselect certain series within the chart of the second comp ...

Adding attributes dynamically to input elements in a React render function

I currently have an input tag inside my render function which looks like this: <input id="time" type="time"> I am now looking to dynamically add the value attribute to it. Is there a way to achieve this in React? Thank you for your help in advance ...

Error message indicating that property 'cause' is not found on type 'Error' is displayed in a new Vue 3 project

After creating a new Vue app using npm init vue@latest, I set it up as follows: https://i.sstatic.net/cbedP.png Next, I replaced the content of the App.vue file with: <script setup lang="ts"> const e = new Error("something failed&quo ...

Is there a way to decrease a field in a MongoDB database on a daily basis?

In the process of constructing an Angular2 application using MEAN stack architecture, I have a field called Remaining Days in my MongoDB database. I am interested in having this field automatically decrement by 1 each day. Do you know if this is possible ...

When zooming out, Leaflet displays both tile layers

I'm currently working on integrating two tile layers along with a control for toggling between them. Below is the code snippet I am using: const layer1: L.TileLayer = L.tileLayer('http://{s}.tile.opencyclemap.org/cycle/{z}/{x}/{y}.png', { ...