0

Hello a service is returning to me the available cards of a client like this:

{
"cards": [
    {
        "id": "545451",
        "name": "Visa",
        "specialConditions": [
            {
                "type": "cardFees",
                "contribution": [
                    {
                        "conditionCode": "freeFees",
                        "validFrom": "2019-12-31",
                        "validTo": "4712-12-31"
                    }
                ]
            }
        ]
    },
    {
        "id": "434342",
        "name": "Mastercard"
    }
]
}

as you can see the cards are an Array the SpecialConditions of it also an Array and the contribution is also an Array.

What i want is to create a data table that displays in 1 line the card.name + the card.specialCondition.type + the card.specialCondition.contribution.conditionCode but i also want to display this line ONLY when a card has a contribution. That means that the mastercard card in the payload i posted would never show in this table

How i came to the result i approach right now is the following code

<div *ngIf="products.cards.length > 0">
<table class="table table-bordered">
<thead>
    <tr>
        <th scope="col">Name</th>
        <th scope="col">Type</th>
        <th scope="col">Condition Type</th>
        <th scope="col">From</th>
        <th scope="col">To</th>
    </tr>
</thead>
<tbody>
    <tr *ngFor="let card of products.cards; let i = index">
        <td *ngIf="card.specialConditions">{{card.name}}</td>
        <td *ngFor="let specialCondition of card.specialConditions; let j = index">{{specialCondition.type?specialCondition.type: 'x'}}</td>
        <td *ngFor="let specialCondition of card.specialConditions; let j = index">{{specialCondition.contribution[0].conditionCode?specialCondition.contribution[0].conditionCode: 'x'}}</td>
        <td *ngFor="let specialCondition of card.specialConditions; let j = index">{{specialCondition.contribution[0].validFrom?(specialCondition.contribution[0].validFrom | date:'dd.MM.yyyy'): 'x'}}</td>
        <td *ngFor="let specialCondition of card.specialConditions; let j = index">{{specialCondition.contribution[0].validTo? (specialCondition.contribution[0].validTo | date:'dd.MM.yyyy'): 'x'}}</td>
    </tr>
</tbody>
</table>
</div>

But i am quite sure that there is a much better approach as that. But i couldnt find out. When i try to wrap the specialConditions ngFor in a span or div or a new html element the table was showing very weird thats why i decided to create for each line a new ngFor

1 Answer 1

1

The only you need is ng-container

As you has an array inside an array inside an array looks like more complex than really is but you can do some like

<tbody>
    <ng-container *ngFor="let card of products.cards; let i = index">
      <ng-container *ngIf="card?.specialConditions as conditions">
        <ng-container
          *ngFor="let conditions of card.specialConditions; let firstCondition = first"
        >
        <tr *ngFor="let contibution of conditions.contribution;let firstContribution=first">
          <td>{{ firstCondition?card.name:'' }}</td>
          <td>{{ firstContribution?conditions.type:'' }}</td>
          <td>{{ contibution.conditionCode || 'x' }}</td>
          <td>{{ contibution.validFrom }}</td>
          <td>{{ contibution.validTo }}</td>
        </tr>
        </ng-container>
      </ng-container>
      <ng-container *ngIf="!card?.specialConditions">
        <tr>
          <td>{{ card.name }}</td>
          <td></td>
          <td></td>
          <td></td>
        </tr>
      </ng-container>
    </ng-container>
  </tbody>

NOTE: You need convert To object javaScript Date your "dates". You need a function like

  transform(cards)
  {
    cards = cards.map((card:any) => {
      if (card.specialConditions)
      {
        card.specialConditions.forEach((condition:any)=>{
          console.log(condition)
          condition.contribution.forEach(x=>{
            console.log(x)
            x.validFrom=new Date(x.validFrom)
            x.validTo=new Date(x.validTo)
          })
        })
      }
      return card
    });
  }

And you pass as

this.transform(this.products.cards)

In the little stackblitz I use in ngOnInit, but really I like more this transform function belong to the "service" (I imagine your data comes from a service).

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.