1

I am trying to send a wrapper class from lightning component to Apex controller. But it is throwing following error:

This page has an error. You might just need to refresh it.
Error in $A.getCallback() [Cannot read property 'name' of null]
Failing descriptor: {ui:input}

Following are the classes and components:

Wrapper Class:

    public class WrapperAccountContact {

        @AuraEnabled
        public String name{get;set;}

        @AuraEnabled
        public String accountNumber{get;set;}

    }

Apex Controller:

    public class CreateAccountContact {

         @AuraEnabled
        public static void createRecord (String candidates){

            try{
                System.debug('CreateCandidateRecord::createRecord::candidate'+candidates);

                if(candidates != null){
                    WrapperAccountContact obj = (WrapperAccountContact)JSON.deserialize(candidates, WrapperAccountContact.class);
                    Account a = new Account();
                    a.name = obj.Name;
                    a.AccountNumber = obj.AccountNumber;
                    insert a;
                }

            } catch (Exception ex){
                System.debug('Exceptionnnn:'+ex);
            }

        } 

    }

JS Controller:

    ({
        create : function(component, event, helper) {
            console.log('Create record');

            //getting the candidate information
            var candidates = component.get("v.candidate");

            //Validation
            /*if($A.util.isEmpty(candidate.name) || $A.util.isUndefined(candidate.name)){
                alert('Name is Required');
                return;
            }            
            if($A.util.isEmpty(candidate.accountNumber) || $A.util.isUndefined(candidate.accountNumber)){
                alert('AccountNumber is Required');
                return;
            }*/

            //Calling the Apex Function
            var action = component.get("c.createRecord");

            //Setting the Apex Parameter
           /* action.setParams({
                candidate : candidate
            });*/
            action.setParams({ "candidates" : JSON.stringify(candidates) });

            //Setting the Callback
            action.setCallback(this,function(a){
                //get the response state
                var state = a.getState();

                //check if result is successfull
                if(state == "SUCCESS"){
                    //Reset Form
                    /*var newCandidate = {'sobjectType': 'WrapperAccountContact',
                                        'name': '', 
                                        'accountNumber': ''
                                       };
                    //resetting the Values in the form
                    component.set("v.candidate",newCandidate);*/
                    alert('Record is Created Successfully');
                } else if(state == "ERROR"){
                    alert('Error in calling server side action');
                }
            });

            //adds the server-side action to the queue        
            $A.enqueueAction(action);

        }
    })

Lightning Component:

<aura:component controller="CreateAccountContact" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes" 
                access="global">

    <ltng:require styles="/resource/Bootstrap/Bootstrapzip/bootstrap.min.css" 
                  scripts="/resource/JQuery/jquery-3.3.1.min.js,/resource/Bootstrap/Bootstrapzip/bootstrap.min.js"/>
    <aura:attribute name="candidate" type="WrapperAccountContact"/>
<div class="container-fluid">
        <h3>Please Enter Account Information</h3>
        <div class="form-group">
            <label>Name</label>
            <ui:inputText class="form-control" value="{!v.candidate.name}"/>
        </div>
        <div class="form-group">
            <label>AccountNumber</label>
            <ui:inputText class="form-control" value="{!v.candidate.accountNumber}"/>
        </div>

    </div>
    <div class="col-md-4 text-center">
        <ui:button class="btn btn-default" press="{!c.create}">Create Contact</ui:button>
  </div>    
</aura:component>

Please let me know if there is any problem with input tags of component and how to resolve the following error:

This page has an error. You might just need to refresh it.
Error in $A.getCallback() [Cannot read property 'name' of null]
Failing descriptor: {ui:input}

Thanks!

0

You never assigned a default value for your attribute. The following change should work:

<aura:attribute name="candidate" type="WrapperAccountContact" default="{}" />

Generally speaking, you don't even need to do that, you could just have used a plain Map:

<aura:attribute name="candidate" type="Map" default="{}" />
1
  • The first option doesn't seem to work though.
    – Jayant Das
    Mar 15 '19 at 16:21
0

You won't be able use you attribute declared with type of a custom apex with ui:inputText. Your primary issue is that your attribute is still null as you haven't instantiated the value candidate but only declared it. Even if you assign a default value, you will not be able to fetch the details in JS.

<aura:attribute name="candidate" type="WrapperAccountContact"/>

Your options:

  1. Either declare individual fields for the values, as below and then use in JS to send it over to Apex:

    <aura:attribute name="name" type="string"/>
    <aura:attribute name="accountNumber" type="string"/>
    
    ...
    <ui:inputText class="form-control" value="{!v.name}"/>
    <ui:inputText class="form-control" value="{!v.accountNumber}"/>
    
  2. Or use a Map:

    <aura:attribute name="candidate" type="Map" default="{}"/>
    
4
  • Hi Jayant, Thanks for your answer. The form may contain more than 15 fields and the data needs to be inserted into multiple objects. Is it good practice to declare morethan 15 attributes? Is there any option to use wrapper class? Thanks!
    – user755806
    Mar 16 '19 at 3:35
  • Unfortunately you cannot create an instance of custom apex classes but only sobjects. As for attributes, while you can declare 15 attributes but better use Map in that case.
    – Jayant Das
    Mar 16 '19 at 3:38
  • Thanks Jayant, Can you please guide me how to set the values into Map , how it can be retrieved in JS also what should be the method parameter of Apex controller? Thanks1
    – user755806
    Mar 16 '19 at 5:02
  • Just declare the attribute as Map on component and then deserialize it in apex using Map as well.
    – Jayant Das
    Mar 16 '19 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.