SFDC Stop - Always the latest about Salesforce


Full Tutorial Series with videos, free apps, live sessions, salesforce consulting and much more.


Telegram logo   Join our Telegram Channel

Saturday, 12 January 2019

Salesforce Lightning Tutorial Part 6 | Receiving data from Apex Controller in JSON format

Welcome to the 6th tutorial in Salesforce Lightning Tutorial Series. In this tutorial, we'll learn about how we can use JSON format to communicate between Lightning Component and Apex Controller in our Salesforce Org.

When we deal with lightning components, the most easier approach is to create aura enabled methods in our controller that accept 1 or more parameters according to the data that we need to pass to our apex class and that method return an object that we receive and store in an aura attribute in our lightning component.

This approach is easier but becomes more complex as we need to send some complex data to our lightning component. The whole code that I am going to use in this tutorial is present in the json branch of my existing github repository that you can access by clicking here.

Real Life Use Case

Let's consider a simple use case:-

I need to display my account details along with the related contacts and the related opportunities in my lightning component. For now, my account id is hardcoded so what I can think of is to create a method that returns an account object. Create another method that returns a list of contacts associated with the account and create another method that returns a list of opportunities associated with my account. So, in this case, I need to call these methods one by one from my lightning component and set the data.

What is JSON ?

JSON stands for "JavaScript Object Notation". If you make an object in JavaScript, it's of the form:-

{
      key1: value1,
      key2: value2
}

So, you can say that it's a map of key value pairs, similarly, for an array we have:-

[{
      key1: value1,
      key2: value2
},
{
      key1: value1,
      key2: value2
},
{
      key1: value1,
      key2: value2
}]

An array consists of multiple objects and we can also have an array inside an object as a value for a key.

By converting the data into JSON for the above mentioned use case, we can call a single function by sending all the required parameters as a JSON String to the apex controller and similarly, receiving all the data as a JSON string. That JSON string will consists of the account fields with values as well as the list of contacts and the list of opportunities related to that account.

It's time to code

Now, let's jump onto the sample code I prepared for our use case and see the communication using JSON strings in action.

JSONDemoController

Let's have a look at our apex controller first of all as we're forming the structure of our JSON data here and will be sending it to our component.


As you can see in the above code, I have made a wrapper class named ResponseJSONWrapper which is responsible to send all data to our lightning component. Now, for my use case, I need to send the account data as well as the related contacts and opportunities to the lightning component. I am using 4 fields of account to display i.e. id, name, industry and annualRevenue. So, created 4 variables in our wrapper class for this. After that I have created a list of contact named as contactList and a list of opportunity named as opportunityList in our wrapper.

Above this, I have created a method named:- getAccountWithRelatedDataById which is getting the id of account as a parameter and is returning the JSON string as the response which will be used by our lightning component. Inside this method, I have initialized a string response and then I made an object of ResponseJSONWrapper class named wrapper. Then I queried the list of accounts where the id is the accountId passed as a parameter to this method. I stored the list of account in accountList variable and this list will contain only one account record as each record has a unique id in salesforce. So, after checking that we got account list with records, I am getting the account record using accountList.get(0); and then assigning my wrapper class fields:- id, name, industry, annualRevenue with this account object's id, name, industry and annual revenue. So, our account data is set in wrapper now. Now, it's time to set contactList and opportunityList variable of our wrapper.

To do that, I have queried the contact list and opportunity list related to that account by specifying the account id in the where condition. Then, I assigned the queried contact list and opportunity list to wrapper's contactList and opportunityList variable and finally returned that wrapper by converting it into JSON using JSON.serialize(wrapper);

JSON.serialize() method, takes an object as a parameter and returns the JSON String which is returned by our method as a response. This JSON string consists of our account details as well our contact and opportunity list. If you call this method directly, and debug the string returned you'll see the below response:-

{"opportunityList":[{"attributes":{"type":"Opportunity","url":"/services/data/v44.0/sobjects/Opportunity/0067F0000048mtBQAQ"},"Id":"0067F0000048mtBQAQ","Name":"Burlington Textiles Weaving Plant Generator","Amount":235000.00,"CloseDate":"2017-06-10"}],"name":"Burlington Textiles Corp of America","industry":"Apparel","id":"0017F000009cscwQAA","contactList":[{"attributes":{"type":"Contact","url":"/services/data/v44.0/sobjects/Contact/0037F00000666yLQAQ"},"Id":"0037F00000666yLQAQ","Name":"Jack Rogers","Phone":"(336) 222-7000","Email":"jrogers@burlington.com"},{"attributes":{"type":"Contact","url":"/services/data/v44.0/sobjects/Contact/0037F00001B4rIEQAZ"},"Id":"0037F00001B4rIEQAZ","Name":"Rahul Malhotra","Phone":"(336) 222-7000","Email":"rahul@sfdcstop.com"}],"annualRevenue":350000000}

You can see the keys I highlighted in above JSON are the variables of our wrapper class and the value we assigned to these variables in the code. Now our next task is to get the data from this JSON in our lightning component and display it there. Notice that in our wrapper, I have name and industry of type string so the value to these keys are also in string format i.e. enclosed in "" whereas annualRevenue is of type decimal so it's value is also a decimal in json and not enclosed in "".

JSONDemoApp

For this tutorial, I created a separate app named as JSONDemoApp. The code for it is given below:-

As you can see above, I have made a simple lightning application which is extending force:slds so that we can use slds classes in our lightning component. We are calling JSONComp component and passing a record it in it as a parameter. The recordId passed is actually the id of an account in my org.

JSONComp

Moving on to the JSONComp component below:-


As you can see in the above code, I have made an init handler which is calling doInit function of my lightning controller as my component is loaded. For this tutorial, I am fetching all data in doInit only to keep it simple and displaying the data in our component. Now, I have made 3 aura attributes to store our data.

First attribute has a name account and is of type Object which is going to store our account data whose record id is passed. Second attribute has a name contacts and is of type List which is going to store our list of contacts associated with this account. Third attribute has a name opportunities and is also of type List which is going to store the list of opportunities associated with this account.

Then, I have made a simple div with slds-grid slds-wrap class so that I can divide my container in 12 columns. Inside that, I have made 1 column of width 1/12, another column of width 10/12 and another column of width 1/12. So that I can display all my data in middle column having width 10/12 which is automatically displayed in the middle of the page.

Inside the middle div, you can see that I am displaying all my data. My account details are displayed using the account object attribute. For ex:- to display the name I am using {!v.account.name} i.e. my account object followed by the key which is having the value. Remember, we studied above that our js objects are like the key-value pair ? So, in my doInit method which we're going to study in a bit, I have received the account data from apex controller and stored it in an account js object which is like this:-

{
      name: account name,
      industry: account industry,
      annualRevenue: 120000
}

It consists of keys which are mainly account field names with their values. For the sake of demo, I have fetched only 3 fields of account from my apex, you can use as many fields as you want.

In the contacts and opportunities aura attribute, I am storing a list of contact and opportunity objects respectively. I am displaying the related contacts using an aura:iteration on v.contacts in which I am assigning each contact object in list to a variable named contact (var="contact") and I am displaying the contact name, phone and email inside using the api names of contact fields for name, phone and email. As, in this case, I have directly assigned the queried contacts list to the aura attribute instead of creating a separate js object or array. We'll see all this assignment in a bit. I am using aura:iteration tag which works like a loop on the value assigned to items attribute like here, the value is v.contacts which is a list to be iterated. Similarly, for Opportunity, I am using Name, Amount, CloseDate field api names to show each opportunity data by iterating on v.opportunities.

JSONCompController

Below is the js controller code that consists of doInit method which is called as the component is initialized and inside it's body it's calling fetchAccountData method of helper. So, it's time to jump onto the helper to see how we processed our JSON data coming from the apex controller and set the aura attributes.


JSONCompHelper

Let's have a look at our final code, i.e. the code for helper method below:-

As you can see above, it consists of fetchAccountData method which was called from our controller's doInit method i.e. automatically called as the component is initialized or loaded. First of all, I am assigning he reference to getAccountWithRelatedDataById method to the fetchData variable. Then, we need to pass the account id as a parameter while calling this apex method from component, so I got the account id from the recordId attribute and stored it in a js variable named:- recordId. After that, I am setting the apex method param of account id with my record id variable using the setParams method. Finally, I have defined a callback for this call using setCallback method and enqueued this action using $A.enqueueAction. It's all simple format to call an apex controller's aura enabled method in lightning component that we've studied in the previous tutorials too, so I'll not go into deep.

Let's have a look at the code inside the callback, if the state is success, then I am going to process my JSON data otherwise, I am simply going to show an alert with message Unable to fetch data from server. If the request was successful, I got the JSON string as a response that I can access using response.getReturnValue() method, this string is in JSON format so I converted that JSON string into a JavaScript Object by wrapping it with JSON.parse() method which is used to parse a JSON string and finally stored it in a variable called responseObj.

var responseObj = JSON.parse(response.getReturnValue());

Finally, I need to extract the values using keys from my JSON and set the aura attributes for contact list, opportunity list and account. I created a new JavaScript Object to store the account data with keys:- name, industry and annualRevenue. I stored this js object in the account variable and finally set the aura attribute using component.set() method. Notice that I am assigning the contacts and opportunities aura attributes directly using responseObj.contactList and responseObj.opportunityList as I am getting these lists directly in JSON.

This is the reason I need to specify the API names of fields while displaying the contact and opportunity objects, As the queried lists are directly assigned to aura attributes and while displaying each record, the field api name serve as key. Whereas, the account object assigned to aura attribute is created manually in js, so I need to use the keys I specified in the object rather than the API name.

The final Output will be as shown below:-



Note:- I tried to cover multiple concepts in this tutorial like:-

  1. Aura attributes of object and list type. 
  2. Creating your own JS object and using in component to display data.
  3. Using a wrapper class to form JSON output.
  4. Accessing queried lists and assigning them directly to aura attributes.

So, if you need to display this data, you can optimize this code a lot to do it in much lesser steps. Give it a try and let me know how you did it in the comments section below. Also, in this post our data was related to each other but we used wrapper class which is suitable to combine unrelated data too. Give it a try too. I am excited to see what you'll make..!!

In the next tutorial, we'll see how we can send the data from our lightning component to apex controller in JSON format. If you liked this post, make sure to share it in your network and also let me know your feedback in the comments section below.

Happy Trailblazing..!!

2 comments:

  1. Please provide video for this tutorial.

    ReplyDelete
    Replies
    1. Thank you for your suggestion. Will surely add a video on the same. Stay tuned at:- https://www.youtube.com/c/sfdcstop

      Delete