2

I have a LWC where i want to iterate over different lists of Opportunities in a wrapper.

Currently im using:

import { LightningElement,wire } from 'lwc';
import OppRecords from '@salesforce/apex/kanbanLWCcontroller.getOpportunity';

export default class KanbanLWC extends LightningElement {
    @wire(OppRecords) allOppsRecords;

}

Html file:

<template if:true={allOppsRecords}>
        <template for:each={allOppsRecords.stage1.data} for:item="stage1Rec">                                         
            <c-single-opp-card opportunity={stage1Rec} key={stage1Rec.Id}></c-single-opp-card>                              
        </template>
<template for:each={allOppsRecords.stage2.data} for:item="stage2Rec">                                         
            <c-single-opp-card opportunity={stage2Rec} key={stage2Rec.Id}></c-single-opp-card>                              
        </template>
</template>

Apex controller:

 public with sharing class kanbanLWCcontroller {

        @AuraEnabled(Cacheable = true)
        public static opportunityWrapper getOpportunity() 
        {
            opportunityWrapper newWrap = new opportunityWrapper ();

            for(Opportunity opportunities: [Select Id, Name,StageName, Amount, Account.Name, CloseDate FROM Opportunity])
            {
                if(opportunities.StageName == 'Prospecting')
                {
                    newWrap.stage1.add(opportunities);
                }
                if(opportunities.StageName == 'Qualification')
                {
                    newWrap.stage2.add(opportunities);
                }
            }
            return newWrap;
        }
    }

Wrapper class:

public class opportunityWrapper {
    @auraEnabled
    public list<Opportunity> stage1= new list<Opportunity>();
    @auraEnabled
    public list<Opportunity> stage2= new list<Opportunity>();
}

Right now, im getting error 'Cannot read property 'data' of undefined'. Can anyone please help me on how to display the wrapper data correctly in this LWC?

2 Answers 2

1

There are few issues, first I will start with when to do if check.

if the wire is successfull the returned wrapper will be in {allOppsRecords.data}. So your first if should be to check if data exists.

Secondly the way template for:each is used is wrong. for:each={allOppsRecords.stage1.data} should be for:each={allOppsRecords.data.stage1}

Also, I would also advise adding extra if before reaching each template for:each

<template if:true={allOppsRecords.data}>

    <template if:true={allOppsRecords.data.stage1}>
        <template for:each={allOppsRecords.data.stage1} for:item="stage1Rec">                                         
                <c-single-opp-card opportunity={stage1Rec} key={stage1Rec.Id}></c-single-opp-card>                              
        </template>
    </template>


    <template if:true={allOppsRecords.data.stage2}>
        <template for:each={allOppsRecords.data.stage2} for:item="stage2Rec">                                         
                <c-single-opp-card opportunity={stage2Rec} key={stage2Rec.Id}></c-single-opp-card>                              
        </template>
    </template>

</template>

Src: https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.apex

2
  • Hi Pranay, thanks a lot for the answer. I tried this way but it still showed me error. I have used another approach which worked for me and i have mentioned it in my answer. Sep 24, 2019 at 12:46
  • @Akshay, what you implemented is using imperative method while you were asking wired method in question. Pranay answered you to solve when getting results in wired method. Both are correct - if you are getting error in this approach, you are probably going wrong somewhere else in code. Sep 24, 2019 at 14:13
0

I tried what you suggested i.e. {allOppsRecords.data.stage1}. But it still showed me error 'Cannot read property 'stage1' of undefined'. So i tried it another way and it worked for me,

Html file:

<template for:each={stage1Records} for:item="stg1">    
                    <c-single-opp-card opportunity={stg1} key={stg1.Id}></c-single-opp-card>                              
</template>

.js file:

import { LightningElement, track } from 'lwc';
import OppRecords from '@salesforce/apex/kanbanLWCcontroller.getOpportunity';

export default class KanbanLWC extends LightningElement {

@track allOppsRecords;
@track stage1Records;
@track stage2Records;

    connectedCallback() {

        OppRecords()
        .then(result => {
            this.allOppsRecords = result;
            this.stage1Records= this.allOppsRecords.stage1;
            this.stage2Records= this.allOppsRecords.stage2;

            this.error = undefined;      
        })
        .catch(error => {
            this.error = error;
            this.allOppsRecords = undefined;
        })
    }

}

Here, i've used connectedCallback() and replaced @wire with @track because the data is dynamic and will change.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .