+ Start a Discussion
Herish SurendranHerish Surendran 

How to pass parameters as wrapper class object from aura component to method in apex class

Lightning Application
<aura:application >
    <c:WrapperComponent/>
</aura:application>

Lightning component
<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" controller="person" >
    <aura:attribute type="person.WrapperClass" name="testAttribute" />
    
    <lightning:input value="{!v.testAttribute.firstName}" name="first"/>
    
    <lightning:input value="{!v.testAttribute.lastName}" name="last"/>
                    <button class="slds-button slds-button_brand" onclick="{!c.submit}">Submit</button>

</aura:component>

Controller of component
({
	submit : function(component, event, helper) {
        
		 var action = component.get("c.getSuccess");
        action.setParams({ 
            obj : component.get('v.testAttribute')
        });
        
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {

                alert("From server: " + response.getReturnValue());

            }
            else if (state === "INCOMPLETE") {
                alert("From server : Sorry server call is incomplete");
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + 
                                 errors[0].message);
                    }
                } else {
                    console.log("Unknown error");
                }
            }
        });
        $A.enqueueAction(action);
    }
	
})

Ape
global with sharing class person {
   
    
    public class WrapperClass {
    @AuraEnabled
        public String firstName;
    @AuraEnabled
        Public String lastName;        
}
    @AuraEnabled
    public Static String getSuccess(WrapperClass obj){
        String r ='';
        if(obj.firstName == 'text' && obj.lastName=='text')
        { r='hi';}
        
		return r;
        
    }    

}

x class
Herish SurendranHerish Surendran
I written the above code and when I preview the component using Lightning Application, I get 2 errors.

error 1 - " Uncaught TypeError: Cannot read property 'firstName' of null throws at https://herishsurendran-dev-ed.lightning.force.com/auraFW/javascript/3uHUkqaEy5o9m3W8DAEYIw/aura_prod.js:544:410 "

error 2 - " Uncaught TypeError: Cannot read property 'lastName' of null throws at https://herishsurendran-dev-ed.lightning.force.com/auraFW/javascript/3uHUkqaEy5o9m3W8DAEYIw/aura_prod.js:544:410 "
Jessica RiffeJessica Riffe
Set your type of your wrapper class to Object for one or Object[] for multiple.  
<aura:attribute type="Object" name="testAttribute" />

 
Herish SurendranHerish Surendran
Hi Jessica. Thanks for the reply. Can you please elaborate on what changes do i need to do as I have just started learning salesforce
Herish SurendranHerish Surendran
Hi Jessica. Thanks for your reply. I have just started learning Salesforce. Can you please elaborate on what changes do I need to do. Or can you make the whole changes and put it back here as a reply
Jessica RiffeJessica Riffe
In addition to typing the wrapper class as an object in your cmp file, 

You need to make a constructor for your wrapper class, which, may or may not be necessary for your example.
global with sharing class person {
    
    public class WrapperClass {
        @AuraEnabled
        public String firstName;
        @AuraEnabled
        public String lastName; 

        public WrapperClass(String fName, String lName){
            this.firstName = fName;
            this.lastName = lName;
        }
    }
}
To pass the wrapper class from your aura component to your apex class, you are going to need to serialize it.
var testAttribute = component.get('v.testAttribute');

action.setParams({ 
    obj : JSON.stringify(testAttribute)
});
To receive it into your apex class
@AuraEnabled
public Static String getSuccess(string objString){
    WrappClass wc = (WrapperClass)system.JSON.deserializeStrict(obj, WrapperClass.class);
    String r ='';
    if(wc.firstName == 'text' && wc.lastName=='text'){
        r = 'hi';
    }   
	return r;
}
Herish SurendranHerish Surendran
I followed your code and still I am getting the same errors
Herish SurendranHerish Surendran
error 1 - " Uncaught TypeError: Cannot read property 'firstName' of null throws at https://herishsurendran-dev-ed.lightning.force.com/auraFW/javascript/3uHUkqaEy5o9m3W8DAEYIw/aura_prod.js:544:410 "

error 2 - " Uncaught TypeError: Cannot read property 'lastName' of null throws at https://herishsurendran-dev-ed.lightning.force.com/auraFW/javascript/3uHUkqaEy5o9m3W8DAEYIw/aura_prod.js:544:410 "
Jessica RiffeJessica Riffe
Your errors are because when the component is initialized, the wrapper class is null.  Therefore, you cannot pull the first and last name off the null testAttribute.
<aura:attribute type="person.WrapperClass" name="testAttribute"  default="{}" />
Herish SurendranHerish Surendran
Hey Jessica I tried but I but i am not able to type anything in those two input fields 
Herish SurendranHerish Surendran
global with sharing class person {
    
    
    public class WrapperClass {
        @AuraEnabled
        public String firstName;
        @AuraEnabled
        public String lastName; 

        public WrapperClass(String fName, String lName){
            this.firstName = fName;
            this.lastName = lName;
        }
    }
    @AuraEnabled
public Static String getSuccess(string obj){
    WrapperClass wc = (WrapperClass)system.JSON.deserializeStrict(obj, WrapperClass.class);
    String r ='Herish';
    if(wc.firstName == 'text' && wc.lastName=='text'){
        r = 'hi';
    }   
	return r;
}   

}
 
<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" controller="person" >
    <aura:attribute type="person.WrapperClass" name="testAttribute" default=""/>
    
    <lightning:input value="{!v.testAttribute.firstName}" name="first"/>
    
    <lightning:input value="{!v.testAttribute.lastName}" name="last"/>
                    <button class="slds-button slds-button_brand" onclick="{!c.submit}">Submit</button>

</aura:component>
 
({
	submit : function(component, event, helper) {
        var testAttribute = component.get('v.testAttribute');
		 var action = component.get("c.getSuccess");
        action.setParams({ 
            obj : JSON.stringify(testAttribute)

        });
        
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {

                alert("From server: " + response.getReturnValue());

            }
            else if (state === "INCOMPLETE") {
                alert("From server : Sorry server call is incomplete");
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + 
                                 errors[0].message);
                    }
                } else {
                    console.log("Unknown error");
                }
            }
        });
        $A.enqueueAction(action);
    }
	
})
 
<aura:application >
    <c:WrapperComponent/>
</aura:application>

 
Herish SurendranHerish Surendran
I am not able to figure out where I went wrong
Jessica RiffeJessica Riffe
What is the value of testAttribute prior to sending it to the server?  Set some console.log statements or a debugger and look at the values in chrome.
Herish SurendranHerish Surendran
I used console log and check the value of testAttribute in chrome. It printed the value as {} in the console and it also mentioned error saying that " Error message: Malformed JSON: Expected '{' at the beginning of object