0

I have a content in a *ngFor loop. When I click on the content, like an accordion, I call a function passing the id of that object that returns the detail of the object. The problem is that now, when I click, It changes for each accordion and not separately. the html is

<div class="card" *ngFor="let data of datas" (click)="fetchData(data.dataId); data.expanded = !data.expanded" style="cursor:pointer; width: 100%;">
    <div class="card-body" style="display:flex">
        <h5 class="card-title">{{data.name}} </h5>
    </div>
    <ng-container *ngIf="data.expanded">
        {{dataContent.descriptionDetail}}
    </ng-container>
</div>

and in my component

fetchData(dataId:number) {
        this.service.fetchData(dataId).subscribe(
            (result) => {
                this.dataContent = result;
                console.log(result);
            }
        );
    }

If I click in the first accordion, i get the correct dataContent. But if I click the second one, it gets me the second dataContent value correctly but also in the first accordion. Thanks

Atlas91
  • 5,754
  • 17
  • 69
  • 141
  • 2
    Can you create a stackblitz to reproduce the issue? – Nicholas K Dec 03 '19 at 17:59
  • I can't create an example for this issue because i don't know where fetch the data. But what I need, and I can't do, is get the details for each accordion when is expanded. The detail is different for each accordion and I can open all of them and each with their detail. Now, if i open one of more of them, I can only show the detail of the last of in each accordion. – Atlas91 Dec 03 '19 at 18:17
  • You can mock the data.. – Nicholas K Dec 03 '19 at 18:28
  • Have you tried using a (TrackBy)[https://stackoverflow.com/questions/42108217/how-to-use-trackby-with-ngfor] – caden311 Dec 03 '19 at 19:15

1 Answers1

0

The problem is that this.dataContent is a single variable which is being displayed in every ng-container. What you need to do instead is somehow manage a collection of data objects and their respective dataContent.

One approach would be to maintain a collection of objects in, say, a Map like this:

// In your component class
dataContents: Map<any, any> = new Map<any, any>();

fetchData(dataId: number) {
    this.service.fetchData(dataId).subscribe(result => {
        this.dataContents.set(dataId, result);
    });
}

And then in your markup:

<ng-container *ngIf="data.expanded">
    {{dataContents.get(data.id)}}
</ng-container>

See an example here (StackBlitz)

With this approach, you can also avoid fetching the data from the server each time, if you want to. In fetchData you would just wrap the this.service.fetchData call in if (!this.dataContents.has(dataId) || !this.dataContents.get(dataId)).

Matt U
  • 4,970
  • 9
  • 28