简体   繁体   中英

Angular 7 - *ngFor not iterating properly and not considering de-structured object

let package = [{
    "masterPack": [{
        "itemName": "master value",
        "grams": "100",
        "rate": "5",
        "scheme": "ccc"
    }],
    "boostPack": [{
        "itemName": "beginner value",
        "grams": "50",
        "rate": "3",
        "scheme": "ccc"
    }]
}];

Attempt 1: straight forward

const itemName = package[0].masterPack[0].itemName + ' + ' + package[0].boostPack[0].itemName;
    const grams = Number(res[0].masterPack[0].grams) + Number(res[0].boostPack[0].grams);
    const rate = Number(res[0].masterPack[0].rate) + Number(res[0].boostPack[0].rate);
    const scheme = package[0].masterPack[0].scheme;
    this.mergeAll.push({
        itemName,
        grams,
        rate,
        scheme,
    }, ...this.package[0].masterPack);
    console.error('final', this.mergeAll);

Attempt 2: for-loop

for (let i = 0; i < package[0].masterPack.length; i++) {
    const itemName = package[0].masterPack[i].itemName + ' + ' + package[0].boostPack[i].itemName;
    const grams = Number(res[0].masterPack[i].grams) + Number(res[0].boostPack[i].grams);
    const rate = Number(res[0].masterPack[i].rate) + Number(res[0].boostPack[i].rate);
    const scheme = package[0].masterPack[i].scheme;
    this.mergeAll.push({
        itemName,
        grams,
        rate,
        scheme,
    }, ...this.package[0].masterPack);
    console.error('final', this.mergeAll);
}

Here i'm trying to show two div as follow

  <div *ngFor="data of mergeAll">
            <div class="one">
                special offer: master Edition + beginner value // ex: masterPack.itemName + '+' addOnPack.itemName
                total grams : 107 // ex: masterPack.grams + '+' addOnPack.grams
                total price(no gst) : Rs 8 // ex: masterPack.rate + '+' addOnPack.rate
                you purchased under : ccc ex: masterPack.scheme
            </div>
            <div class="two">
        
                Default offer: master Edition // ex: masterPack.itemName
                total grams : 107 // ex: masterPack.grams
                total price(no gst) : Rs 8 // ex: masterPack.rate
                you purchased under : ccc ex: masterPack.scheme
            </div>
        </div>

issue: I can able to see two objects inside this.mergeAll but if use *ngFor = "data in mergeAll" , its not iterating values properly. means, it's not considering ...this.package[0].masterPack

Could some one tell me how simplify the above two failed attempt to achieve the output.?

Thanks

You must define data variable first, and use of instead of in :

<div *ngFor="let data of mergeAll">
        <div class="one">
            special offer: master Edition + beginner value // ex: masterPack.itemName + '+' addOnPack.itemName
            total grams : 107 // ex: masterPack.grams + '+' addOnPack.grams
            total price(no gst) : Rs 8 // ex: masterPack.rate + '+' addOnPack.rate
            you purchased under : ccc ex: masterPack.scheme
        </div>
        <div class="two">
    
            Default offer: master Edition // ex: masterPack.itemName
            total grams : 107 // ex: masterPack.grams
            total price(no gst) : Rs 8 // ex: masterPack.rate
            you purchased under : ccc ex: masterPack.scheme
        </div>
    </div>

The below should work for you.

<div *ngFor="let data of packag; let i = index" class="special">
  <h1>Special Offer</h1>
    <div>
    Special Offer: {{data.masterPack[i].itemName}} {{data.boostPack[i].itemName}}
    </div>
  <div>
    Total grams: {{sumNumbers(data.masterPack[i].grams, data.boostPack[i].grams)}}
    </div>
  <div>
    Total price(no gst): {{sumNumbers(data.masterPack[i].rate, data.boostPack[i].rate)}}
    </div>
  <div>
    You purchased under: {{data.masterPack[i].scheme}}
    </div>
  </div>

<div *ngFor="let data of packag; let i = index" class="base">
  <h1>Base Offer</h1>
    <div>
    Special Offer: {{data.masterPack[i].itemName}}
    </div>
  <div>
    Total grams: {{data.masterPack[i].grams}}
    </div>
  <div>
    Total price(no gst): {{data.masterPack[i].rate}}
    </div>
  <div>
    You purchased under: {{data.masterPack[i].scheme}}
    </div>
</div>

Method in component.ts

sumNumbers(a, b) {
    return Number(a) + Number(b);
  }

If you want to have single array, the below loop will create single collection for both special and base offer.

for (let i = 0; i < this.packag[0].masterPack.length; i++) {
    let itemName = this.packag[0].masterPack[i].itemName + ' + ' + this.packag[0].boostPack[i].itemName;
    let grams = Number(this.packag[0].masterPack[i].grams) + Number(this.packag[0].boostPack[i].grams);
    let rate = Number(this.packag[0].masterPack[i].rate) + Number(this.packag[0].boostPack[i].rate);
    let scheme = this.packag[0].masterPack[i].scheme;
    this.mergeAll.push({
        itemName,
        grams,
        rate,
        scheme,
    });
    itemName = this.packag[0].masterPack[i].itemName;
    grams = Number(this.packag[0].masterPack[i].grams);
    rate = Number(this.packag[0].masterPack[i].rate);
    scheme = this.packag[0].masterPack[i].scheme;
    this.mergeAll.push({
        itemName,
        grams,
        rate,
        scheme,
    });

Template

<div *ngFor="let data of mergeAll" class="base">
  <h1>{{data.rowType}}</h1>
    <div>
    Special Offer: {{data.itemName}}
    </div>
  <div>
    Total grams: {{data.grams}}
    </div>
  <div>
    Total price(no gst): {{data.rate}}
    </div>
  <div>
    You purchased under: {{data.scheme}}
    </div>
</div>

Stackblitz link

https://stackblitz.com/edit/angular-ivy-fxztwk?embed=1&file=angular.json

this another way in case you just want to display the packages without update of transfer the data by just using ngFor and, keyvalue pipe

<ng-container *ngFor="let data of package">
    <div *ngFor="let v of data | keyvalue;">
        <h3>
            {{v.key}}
        </h3>
        <ng-container *ngIf="v.value[0] as item">
            <div>
                <div>
                    itemName : {{item.itemName}}
                </div>
                <div>
                    grams : {{item.grams}}
                </div>
                <div>
                    rate :{{item.rate}}
                </div>
                <div>
                    scheme : {{item.scheme}}
                </div>
            </div>
        </ng-container>
    </div>
</ng-container>

this line <ng-container *ngIf="v.value[0] as item"> just to create a variable for v.value[0] so I don't need to keep writing v.value[0]. .

another point my answer is just to show that it is possible to use ngFor and keyvalue pipe to display package so this may help to simplify you logic

stackblitz demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM