7

I'm trying to use wrapper class in lwc, but getting one error "Uncaught afterRender threw an error in 'c:wrapperComponent' [Cannot read property 'Id' of undefined] Callback failed: aura://ComponentController/ACTION$getComponent" I'm not able to figure out what's wrong.

HTML:

<template>
    <lightning-card title="LWC Wrapper Component">
        <template if:true={wrappers.data}>
            <template for:each={wrappers.data} for:item="wrapper">
                <p key={wrapper.con.Id}>{wrapper.con.Name}

                </p>

            </template>
        </template>
    </lightning-card>
</template>

js:

import { LightningElement, wire } from 'lwc';
import getWrapperList from '@salesforce/apex/WrapperClass.getWrapperList';

export default class WrapperComponent extends LightningElement {
    @wire(getWrapperList) wrappers;
}

Controller Class:

public with sharing class WrapperClass {

    @AuraEnabled(cacheable=true)
    public static List<wrapp> getWrapperList() {
        List<wrapp> wrapperList = new List<wrapp>();
            for(Contact con : [SELECT Id, Name, Title, Phone, Email FROM Contact LIMIT 100]){
                wrapp obj = new wrapp(false,con);
                wrapperList.add(obj);
            }
        return wrapperList;
    }

}

wrapper Class:

public class wrapp{
    @AuraEnabled
    public Contact con{get;set;}
    @AuraEnabled
    public boolean selected{get;set;}

    public wrapp(boolean selected,Contact con){
        con = con;
        selected = selected;            
    }
}
4
  • In wrapper class constructor, try accessing and assigning the property with this keyword. 'this.con = con;'
    – Raul
    Mar 30, 2019 at 10:05
  • 2
    @Raul You should have added an answer, not a comment.
    – sfdcfox
    Mar 30, 2019 at 10:29
  • Thanks @Raul It resolves my issue, could you please explain why using this.con resolves the issue Mar 30, 2019 at 10:54
  • @salesforce Developer... By writing "con = con;" you are assigning the passed in con to itself. By using "this.con" you are assigning the passed in con to the class level con, since "this" represents the class in this context. Incidentally, you also need to use "this." on selected, too. Mar 30, 2019 at 11:31

2 Answers 2

12

This is a quite common problem, with wrapper class if you use same name of property and the parameters of the constructor; you should use 'this' keyword to assign parameter value to property.

public class wrapp{
    @AuraEnabled
    public Contact con{get;set;}
    @AuraEnabled
    public boolean selected{get;set;}

    public wrapp(boolean selected,Contact con){
        this.con = con;
        this.selected = selected;            
    }
}
5

As an alternative, this is how you would approach the same thing but without a public wrapper.

You would leverage the very interesting datatype Map<String, Object> in lieu of an actual wrapper class.

@AuraEnabled (cacheable=true)
public static List<Map<String, Object>> getWrapper() {
  List<Map<String, Object>> wrapperList = new List<Map<String, Object>>();

  for (Contact contact : [SELECT Id, Name, Title, Phone, Email FROM Contact LIMIT 100]) {
    Map<String, Object> wrapp = new Map<String, Object>{
      'selected' => false,
      'con' => contact
    };
    wrapperList.add(wrapp);
  }

  return wrapperList;
}

You must log in to answer this question.

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