Blog Categories

Posted by on Sep 2, 2016 in Blog Series, Featured Blogs, Learn Salesforce Lightning with Examples, Tutorials | 3 comments

Learn Salesforce Lightning with Examples – Part 2 (Handling Apex Messages in Lightning Component)

Learn Salesforce Lightning with Examples – Part 2 (Handling Apex Messages in Lightning Component)

Learn Salesforce Lightning with Examples – Part 2 ( Handling Apex Messages in Lightning Component ) is the second part of the series – “Learn Salesforce Lightning with Examples” where We would share the key practical examples and experience with lightning.We are focusing on Lightning Components for now.

Background,Blog Contributors and Pre-Requisites

To get started for this blog you need to fulfill all the Pre-requisites mentioned here.In this link,you will also get to know the background and blog contributors for this series.

Handling Apex Messages in Lightning Component

Business Case:

Adam is working as a Senior Application Developer in Universal Containers. Company wants to move their traditional (classic version )recruitment app to lighting. Adam needs to do a Proof of Concept by building a custom lighting component for creating the Candidate’s record into Salesforce. Now that he has created the first part which is explained here,He would like to showcase even users know the success or error messages occurring from Apex.This will help users to understand if there have been receiving any error from Apex and Handling Apex Messages in Lightning Component if required with custom messages.

Solution:

Adam decided to handle the error and success messages using wrapper class in apex and then use it displaying the error messages in Apex.

Before getting started,Adam makes sure that he doesn’t miss any pre-requisites mentioned here.Below are the steps Adam takes for creating the solution after completing the pre-requisites.If you have followed my previous blog,then you just need to update the components and follow these steps(Please note that if you just copy paste the complete code then you need not follow my previous blog,but I would insist you to do so if you want to learn in details):

  1. Define Wrapper Class in Apex
  2. Update Apex Class and and method.
  3. Get response(wrapper data) in lightning controller
  4. Test the Application

Define Wrapper Class in Apex

Create a Wrapper Class inside the existing Apex Class or a separate class like this :

    /************************************************************
     Name:      AuraProcessingMessage
     Type:      Wrapper  Class  
     Purpose:   Wrapper  Class to hold error and success 
                message to  display in  lightning component 
    ***********************************************************/
    public class AuraProcessingMessage { 
        
        @AuraEnabled public Boolean isSuccess;
        @AuraEnabled public String errorMsg; //error msg
        @AuraEnabled public String successMsg; //success msg
        
        public AuraProcessingMessage(){
            isSuccess = true;
            errorMsg = '';
            successMsg = '';
        }
    }
 

you need to twist your code accordingly so that the apex code saves messages from wrapper code accordingly.Your complete apex class should look like :

/*
 * DISCLAIMER:
THIS CODE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * */
/************************************************************
 Name: CreateCandidateRecord
 Type: Apex Class  
 Purpose: Apex Class  for  lightning component 
		  CreateCandidateRecordController.cmp
 ***********************************************************/
 

public with sharing class CreateCandidateRecord 
{

    //String Constant for Success Message 
    private static final string  SUCCESS_MESSAGE = 'Record created 
	successfully';
    
    //String Constant for Error Message
    private static final string  ERROR_MESSAGE = 'Error
	Message From Apex: n';
    
    /************************************************************
	* Name :    createRecord
   * Type :    Aura Enabled Method with wrapper return type
   * Purpose:  1.Create a new candidate Record using 
   *             Lightning Component
   *           2.Add Succcess and Error Messages to display in 
   *             Lightning Component 
   **************************************************************/
    @AuraEnabled
    public static AuraProcessingMessage createRecord (Candidate__c candidate){
        
        Savepoint sp = Database.setSavepoint();
        
        //Initializing the wrapper message 
        AuraProcessingMessage returnMessage = new AuraProcessingMessage();
        
        try{
            System.debug('CreateCandidateRecord::createRecord:
			:candidate'+candidate);
            
            if(candidate != null)
            {
                insert candidate;
                //Adding the success message if the record is created
                returnMessage.successMsg=SUCCESS_MESSAGE;
            }
            
        } 
         catch(Exception ex)
         {
            system.debug('Debug Exception Message'+ex.getMessage());
            returnMessage.isSuccess = false;
            
            //Adding the error message if an exception is occured
            returnMessage.errorMsg = ERROR_MESSAGE + ex.getMessage();
            
            //Rollback the transaction if an exception is occured
            Database.rollback(sp);
        }
        //Return the error message
        return returnMessage;
        
    }  
        
    /************************************************************
     Name:      AuraProcessingMessage
     Type:      Wrapper  Class  
     Purpose:   Wrapper  Class to hold error and success 
                message to  display in  lightning component 
    ***********************************************************/
    public class AuraProcessingMessage { 
        
        @AuraEnabled public Boolean isSuccess;
        @AuraEnabled public String errorMsg; //error msg
        @AuraEnabled public String successMsg; //success msg
        
        public AuraProcessingMessage(){
            isSuccess = true;
            errorMsg = '';
            successMsg = '';
        }
    }
}
 

Get response (wrapper data) in lightning controller

In lightning controller Check the Boolean flag if method executed successfully and display error or success message accordingly.Like this :

/*
 * DISCLAIMER:
THIS CODE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * */
/************************************************************
 Lightning Controller  Details
 Name: CreateCandidateRecordController.js
 Type: Lightning Controller 
 Purpose: Controller for  lightning component 
		  CreateCandidateRecordController.cmp
 ***********************************************************/
({
	
    create : function(component, event, helper) {
		console.log('Create record');
        var $k = jQuery.noConflict();
        //getting the candidate information
        var candidate = component.get("v.candidate");
        
        //Validation
        if($A.util.isEmpty(candidate.First_Name__c) || $A.util.isUndefined(candidate.First_Name__c)){
            //Access Custom Label in Javascript
            alert($A.get("$Label.c.FirstNameRequired"));
        }            
        else if($A.util.isEmpty(candidate.Last_Name__c) || $A.util.isUndefined(candidate.Last_Name__c)){
            alert($A.get("$Label.c.LastNameRequired"));
        }
        else if($A.util.isEmpty(candidate.Email__c) || $A.util.isUndefined(candidate.Email__c)){
            alert($A.get("$Label.c.EmailRequired"));
        }
        else if($A.util.isEmpty(candidate.SSN__c) || $A.util.isUndefined(candidate.SSN__c)){
            alert($A.get("$Label.c.SSNRequired"));
        }
        else {
            //Calling the Apex Function
            var action = component.get("c.createRecord");
            
            //Setting the Apex Parameter
            action.setParams({
                candidate : candidate
            });
            
            //Setting the Callback
            action.setCallback(this,function(a){
                //get the response state
                var state = a.getState();
                
                //check if result is successfull
                if(state == "SUCCESS"){
                    //Get the Response From Apex
                    var result = a.getReturnValue();
                    
                    //Check if Success in Apex Class
                    if(result.isSuccess){
                       //Reset Form
                        var newCandidate = {'sobjectType': 'Candidate__c',
                                            'First_Name__c': '',
                                            'Last_Name__c': '',
                                            'Email__c': '', 
                                            'SSN__c': ''
                                           };
                        //resetting the Values in the form
                        component.set("v.candidate",newCandidate);
                        alert(result.successMsg); 
                    } else {
                        alert(result.errorMsg);
                    }
                    
                } else if(state == "ERROR"){
                    alert('Error in calling server side action');
                }
            });
            
            //adds the server-side action to the queue        
            $A.enqueueAction(action); 
        }
        

	}
    
    
})
 

Note : There will be no change in component and application code mentioned in previous post.

Test the Application

Now since We are done with the codes,lets test the application.So in our case,We need to try with the URL format :

https://{Domain Name}.lightning.force.com/c/{App Name}.app

and then you would get a similar page like this :

Lightning App Screen

Error Message

So now if there is any exception/error occurs while apex operations,then you would get an apex error message as an alert which would help you to easily identify the error similar to like this :

ErrorMesg

In the above example,Since the maximum length for the SSN field is set to 9,If you put any numbers beyond it,You will get exception message thrown.

Success Message

If you fill the information without any exception,then you would get a success message as well showing like this :

SuccessMesg

You can also create pop- ups to display these messages in them to give more good look and feel.

You can also download the code from the github repository here.

Hope you enjoyed the blog! Stay tuned and there will be more examples to come ..