Aura.Action attributes in Lightning


<apex:component >
    <aura:attribute name="onClick" type="Aura.Action" >
</apex:component >

An Aura.Action is a reference to an action in the framework. If a child component has an Aura.Action attributes, a parent component can pass in an action handler when it instantiates the child component in its.

Aura.Action is used pass a controller action from a parent component to child component that it contains and is used for on* handlers like onClick.

Limitations for Aura.Action attributes –

Although Aura.Action works for passing an action handler to a child component, its recommend registering an event in the child component and firing the event in the child’s controller instead.Then, handle the event in the parent component.

  • Don’t use cmp.set() in JavaScript code to reset an attribute of  type=”Aura.Action” after it’s previously been set. Doing so generates an error.
  • Don’t use $A.enqueueAction() in the child component to enqueue the action passed to the Aura.Action attribute.

Demonstration –

  1. Create a child component, which contain the Aura.Action attribute type.
  2. Child component also have a on* action handler like onClick.
  3. aura:attribute name should be same as expression inside the onclick action

childAction.cmp –


<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    <aura:attribute name="childAction" type="Aura.Action"/>

    <lightning:button label="Execute Aura.Action" onclick="{!v.childAction}"/>
</aura:component >

  1. Embed the child component in Parent and pass the Aura.Action attribute name here to call the ParentComponent controller.
  2. Define the Controller of the parent component.

parentAction.cmp


<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId" access="global">
     <c:Child childAction="{!c.parentAction}"/ >
</aura:component>

parentActionController.js


({
 parentAction : function(component, event, helper) {
    alert('Aura.Action Parent Compoentnt');
}
})

AuraAction.app


<aura:application extends="force:slds" >
    <c:parentAction/>
</aura:application >

 Instead of an Aura.Action attribute, you could use <aura:registerEvent> to register an onclick event in the child component. You’d have to define the event and create an action in the child’s controller to fire the event. This event-based approach requires a few extra steps but it’s more in line with standard practices for communicating between components.

 Next1 Click here for using aura:registerEvent over Aura.Action attribute

Apex Controller overview in Lightning

Apex controller with method annotated with @AuraEnabled only will be exposed to use in Lightning component.

public with sharing class SimpleServerSideController {

    //Use @AuraEnabled to enable client- and server-side access to the method
    @AuraEnabled
    public static String serverEcho(String firstName) {
        return ('Hello from the server, ' + firstName);
    }
}

Apex controller must follow these requirements.

  1. Methods must be static and marked public or global. Non-static methods aren’t supported.
  2. If a method returns an object, instance methods that retrieve the value of the object’s instance field must be public.
  3. Use unique names for client-side and server-side actions in a component. A JavaScript function (client-side action) with the same name as an Apex method (server-side action ) can lead to hard-to-debug issues. In debug mode, the framework logs a browser console warning about the clashing client-side and server-side action names.

@AuraEnabled Annotaion – The AuraEnabled annotation enables Lightning components to access Apex methods and properties.

  1. Use @AuraEnabled on Apex class static methods to make them accessible as remote controller actions in your Lightning components.
  2. Use @AuraEnabled on Apex instance methods and properties to make them serializable when an instance of the class is returned as data from a server-side action.

Caching Method Results –

To improve runtime performance, set @AuraEnabled(cacheable=true) to cache the method results on the client. To setcacheable=true, a method must only get data, it can’t mutate data.

Marking a method as storable (cacheable) improves your component’s performance by quickly showing cached data from client-side storage without waiting for a server trip. If the cached data is stale, the framework retrieves the latest data from the server. Caching is especially beneficial for users on high latency, slow, or unreliable connections such as 3G networks.

To cache data returned from an Apex method for any component with an API version of 44.0 or higher, you must annotate the Apex method  with  @AuraEnabled(cacheable=true). For example:

@AuraEnabled(cacheable=true)
public static Account getAccount(Id accountId) {
    // your code here
}

Prior to API version 44.0, to cache data returned from an Apex method, you had to call setStorable() in JavaScript code on every action that called the Apex method. For API version of 44.0 or higher, you must mark the Apex method as storable (cacheable) and you can get rid of any setStorable() calls in JavaScript code. The Apex annotation approach is better because it centralizes your caching notation for a method in the Apex class.

Returning Data from Server side Controller  Next1

Attributes in Lightning

Attributes are the most commonly used element to pass data down the component hierarchy as they are simple to use. In order to pass data down from a parent component to its child, simply use the following code:

Parent Component –

<aura:component>
   <aura:attribute name="parentAttribute" type="String"/>
   <c:childComponent childAttribute="{!v.parentAttribute}"/>
</aura:component>

Child Component –

<aura:component>
   <aura:attribute name="childAttribute" type="String"/>
</aura:component>

In this example, the parent component value of parentAttribute is transferred to the childAttribute of the child component via the  {!v.parentAttribute}  expression.

This is perfect if you just want to display the data in a child component. What about if you also want to execute some logic when the attribute’s value changes?

Consider the following updated definition of childComponent :

<aura:component>
   <aura:attribute name="childAttribute" type="String"/> 
   <aura:handler name="change" value="{!v.childAttribute}" action="{!c.onChildAttributeChange}"/>
</aura:component>

With the addition of a change handler, the child component can now trigger the  onChildAttributeChangecontroller function automatically when the value of  childAttribute changes. This allows us to implement some custom logic such as:

({
    onChildAttributeChange : function (component, event, helper) {
        console.log("Old value: " + event.getParam("oldValue"));
        console.log("Current value: " + event.getParam("value"));
    }
})

We now have established a top-down communication chain between the parent and the child component. This can be summarized in these few steps:

  1. parentAttribute value changes
  2. parentAttribute value is transferred to childAttribute
  3. childComponent’s change handler triggers the onChildAttributeChange controller function

This approach works great for processing an attribute. What about multiple attribute changes? If you want to change two or more attributes and then trigger some logic, this method becomes unwieldy. You can either combine the attributes into a larger object (not always practical) or write a complex synchronization algorithm (please don’t). Instead, I recommend methods for multiple attribute changes

This is article from Salesforce developer blog.

Lightning Component Attribute

Component attributes are like member variable in Apex class. Attribute enables you to make component more dynamic.

Use the  tag to add an attribute to the component or app.

All tag must have name and type values.

Supported aura:attribute types

  1. Basic Types
    1. Boolean
    2. Date
    3. DateTime
    4. Decimal
    5. Double
    6. Integer
    7. Long
    8. String
  2. Function Type
  3. Object Type [Standard and Custom Object type]
  4. Collection Type
    1. Array –  An array of item of a defined type
    2. List – An ordered collection of items
    3. Map – Key-value pair. A map can’t contain duplicate keys.
    4. Set – An unordered collection, Contains no duplicate elements
  5. Custom Apex Type
  6. Framework specific type
    1. Aura.Component
    2. Aura.Component[]
    3. Aura.Action

Interview Questions

  1. What are the different type of aura:attributes type you can use in lightning ?
  2. Can you use sObject type in lightning component attribute ?

continue

All about Salesforce Connect

Salesforce Connect is a framework that enables you to view, search, and modify data that’s stored outside your Salesforce org. For example, perhaps you have data that’s stored on premises in an enterprise resource planning (ERP) system. Instead of copying the data into your org, you can use external objects to access the data in real time via web service callouts.

Previously, the only way to integrate external data with Salesforce was to use extract, transform, and load (ETL) tools. That process is time consuming and requires you to copy data into your org that you might never use or quickly becomes stale. In contrast, Salesforce Connect maps data tables in external systems to external objects in your org.

External objects are similar to custom objects, except that they map to data located outside your Salesforce org. External object data is always up to date. Salesforce Connect provides a live connection to external data rather than a copy that consumes storage and must be regularly synced. Accessing an external object fetches the data from the external system in real time.

We recommend that you use Salesforce Connect if most of these conditions apply.

  • You have a large amount of data that you don’t want to copy into your Salesforce org.
  • You need small amounts of data at any one time.
  • You need real-time access to the latest data.
  • You store your data in the cloud or in a back-office system, but want to display or process that data in your Salesforce org.

External objects are not a replacement for ETL. If you need frequent access to large amounts of external data, ETL might still be your best option for optimal performance.

Unsupported features in external objects then custom objects –

  • Data will not stored in external object of your Salesforce org.
  • Formula Fields are not allowed in external object.
  • Workflow and Trigger are not allowed in external object.

Big Object Basics

Big objects allow you to store and manage a massive amount of data on the Salesforce platform.

Big objects provide consistent performance for a billion records or more, and are accessible with a standard set of APIs to your org or external system. Think of all that data! We basically took a gigant-o-ray to the objects you already know and love to create big objects.

  • Standard big objects – example is FieldHistoryArchive
  • Custom big objects

Uses of Big Objects like –

  1. 360° view of Customer – You can store any customer information like transactions, orders, billing details, use a Custom Big object to keep track of every details.

  2. Auditing and Tracking – Keep a long-term view of your users’ Salesforce usage for analysis or compliance purposes.
  3. Historical Archive -Maintain access to historical data for analysis or compliance purposes while optimizing the performance of your core CRM or Lightning Platform applications.

Querying Big Objects –

You can query big objects using standard SOQL or with Async SOQL.

Points to Remember –

  • Big objects support only object and field permissions.
  • You must use the Metadata API to define or add a field to a custom big object. You can’t do it through the UI.
  • SOQL relationship queries are based on a lookup field from a big object to a standard or custom object in the select field list (not in filters or subqueries).
  • Big objects support custom Salesforce Lightning and Visualforce components rather than standard UI elements (home pages, detail pages, list views, and so on).
  • You can create up to 100 big objects per org. The limits for big object fields are similar to the limits on custom objects, and depend on your org’s license type.
  • Big objects don’t support transactions that include big objects, standard objects, and custom objects.
  • To support the scale of data in a big object, you can’t use triggers, flows, processes, and the Salesforce app.

Query Big Object using SOQL and Async SOQL –

Big objects can be queried using SOQL or Async SOQL. Async SOQL uses to handle the massive volume of data that can be kept within a big object. Because Async SOQL queries are run asynchronously, you don’t have to worry about queries timing out.

Generally, you want to use Async SOQL over standard SOQL when you’re dealing with large amounts of data. If you only need a small dataset from a big object, or if you need the results immediately, use standard SOQL. Async SOQL also works on standard and non-big custom objects, but support for those objects is in pilot.

Use standard SOQL when:

  • You want to display the results in the UI without having the user wait for results.
  • You want results returned immediately for manipulation within a block of Apex code.
  • You know that the query will return a small amount of data.
Use Async SOQL when:

  • You are querying against millions of records.
  • You want to ensure that your query completes.
  • You don’t need to do aggregate queries or filtering outside of the index.

 

Future Method in Apex

Future Apex is used to run processes in a separate thread, at a later time when system resources become available.

You use the @future annotation to identify methods that run asynchronously.

Future methods are typically used for:

  • Callouts to external Web services. If you are making callouts from a trigger or after performing a DML operation, you must use a future or queueable method. A callout in a trigger would hold the database connection open for the lifetime of the callout and that is a “no-no” in a multitenant environment.
  • Operations you want to run in their own thread, when time permits such as some sort of resource-intensive calculation or processing of records.
  • Isolating DML operations on different sObject types to prevent the mixed DML error.

Syntax of Future Method :-


global class futureClass {
@future
public static void myFutureMethod(List recordIds) {
List accounts = [Select Id, Name from Account Where Id IN :recordIds];
// process account records to do something
}
}
  • Future method must be static and return type is void always.
  • Parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types.
  •  Future methods can’t take standard or custom objects as arguments.
  • A common pattern is to pass the method a List of record IDs that you want to process asynchronously.

Note

The reason why objects can’t be passed as arguments to future methods is because the object can change between the time you call the method and the time that it actually executes. Remember, future methods are executed when system resources become available. In this case, the future method may have an old object value when it actually executes, which can cause all sorts of bad things to happen.

  • Future methods are not guaranteed to execute in the same order as they are called.
  • If you need this type of functionality then Queueable Apex might be a better solution.

Callout Using Future

To make a Web service callout to an external service or API, you create an Apex class with a future method that is marked with (callout=true).

public class SMSUtils {
// Call async from triggers, etc, where callouts are not permitted.
@future(callout=true)
public static void sendSMSAsync(String fromNbr, String toNbr, String m) {
String results = sendSMS(fromNbr, toNbr, m);
System.debug(results);
}

// Call from controllers, etc, for immediate processing
public static String sendSMS(String fromNbr, String toNbr, String m) {
// Calling 'send' will result in a callout
String results = SmsMessage.send(fromNbr, toNbr, m);
insert new SMS_Log__c(to__c=toNbr, from__c=fromNbr, msg__c=results);
return results;
}
}

 Test Class for Future Method Class – 

To test future methods, enclose your test code between the startTest and stopTest test methods. The system collects all asynchronous calls made after the startTest. When stopTest is executed, all these collected asynchronous processes are then run synchronously. You can then assert that the asynchronous call operated properly.

Note : Test code cannot actually send callouts to external systems, so you’ll have to ‘mock’ the callout for test coverage.

@isTest
global class SMSCalloutMock implements <strong>HttpCalloutMock</strong> {
global HttpResponse respond(HttpRequest req) {
// Create a fake response
HttpResponse res = new HttpResponse();
res.setHeader('Content-Type', 'application/json');
res.setBody('{"status":"success"}');
res.setStatusCode(200);
return res;
}
}
@IsTest
private class Test_SMSUtils {

@IsTest
private static void testSendSms() {
<strong>Test.setMock(HttpCalloutMock.class, new SMSCalloutMock());</strong>
Test.startTest();
SMSUtils.sendSMSAsync('111', '222', 'Greetings!');
Test.stopTest();
// runs callout and check results
List logs = [select msg__c from SMS_Log__c];
System.assertEquals(1, logs.size());
System.assertEquals('success', logs[0].msg__c);
}
}

Important Points – 

Future methods are a great tool, but with great power comes great responsibility. Here are some things to keep in mind when using them:

  • Methods with the future annotation must be static methods, and can only return a void type.
  • The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types; future methods can’t take objects as arguments.
  • Future methods won’t necessarily execute in the same order they are called. In addition, it’s possible that two future methods could run concurrently, which could result in record locking if the two methods were updating the same record.
  • Future methods can’t be used in Visualforce controllers  in  getMethodName(),   setMethodName(), nor in the constructor.
  • You can’t call a future method from a future method. Nor can you invoke a trigger that calls a future method while running a future method.
  • The getContent() and getContentAsPDF() methods can’t be used in methods with the future annotation.
  • You’re limited to 50 future calls per Apex invocation, and there’s an additional limit on the number of calls in a 24-hour period. For more information on limits, see the link below.

All about SOQL Aggregate function

Aggregate functions in SOQL, such as SUM() and MAX(), allow you to roll up and summarize your data in a query.

You can use aggregate functions without using a GROUP BY clause. For example, you could use the AVG() aggregate function to find the average Amount for all your opportunities.

AggregateResult[] groupedResults  = [SELECT AVG(Amount)aver FROM Opportunity];
Object avgAmount = groupedResults[0].get('aver');

Note that any query that includes an aggregate function returns its results in an array of AggregateResult objects. AggregateResult is a read-only sObject and is only used for query results.

Aggregate functions become a more powerful tool to generate reports when you use them with a GROUP BY clause. For example, you could find the average Amount for all your opportunities by campaign.

AggregateResult[] groupedResults = [SELECT CampaignId, AVG(Amount) FROM Opportunity GROUP BY CampaignId];
for (AggregateResult ar : groupedResults) {
        System.debug('Campaign ID' + ar.get('CampaignId'));
        System.debug('Average amount' + ar.get('expr0'));
}

Any aggregated field in a SELECT list that does not have an alias automatically gets an implied alias with a format expri, where i denotes the order of the aggregated fields with no explicit aliases. The value of i starts at 0 and increments for every aggregated field with no explicit alias.

Use aggregate functions in a GROUP BY clause in SOQL queries. Aggregate functions include AVG(), COUNT(), MIN(), MAX(), SUM().

Trigger to Update Contacts on Account Update

trigger AccountTrigger on Account (before update) {
   Map updateAccMap = new Map();
    List updatedContacts = new List();
   for(Integer i=0; i< trigger.new.size(); i++) {
       if(trigger.old[i].ShippingState != trigger.new[i].ShippingState) {
           updateAccMap.put(Trigger.old[i].id, Trigger.new[i]);
       }
   }
   //for(Contact c : [Select Id, AccountId, Account_Updated__c From Contact where AccountId IN :updateAccMap.keySet()]) {
   for(Contact c : [Select Id, AccountId, Account_Updated__c From Contact where AccountId IN :trigger.old]) {
       Account parentAcc = updateAccMap.get(c.AccountId);
       c.Account_Updated__c = true;
          updatedContacts.add(c);
   }
   if(!updatedContacts.isEmpty())
	update updatedContacts;
}

Difference between list for loop and SOQL for loop in Apex

Apex code to update all accounts with null region field with value ‘CAM’.

Using SOQL List for loop – Create a list of sObject result list first and then loop through the list

List accountList = [Select Id, Name,region__c From Account];
List accUpdateList = new List();

for(Account acc : accountList) {
if(acc.regioon__c == null) {
        Account.region__c = 'CAM';
        accUpdateList.add(acc);
    }
}
if(!accUpdateList.isEmpty())
    update accUpdateList ;

Using SOQL for loop – Use the SOQL query in the for loop

List accUpdateList = new List();
for(Account acc : [Select Id, Name,region__c From Account]) {
    if(acc.regioon__c == null) {
        Account.region__c = 'CAM';
        accUpdateList.add(acc);
    }
}
if(!accUpdateList.isEmpty())
    update accUpdateList

SOQL and SOSL query can retrieve either the count of a query or a number of object records.  SOQL for loop retrieves all sObjects using efficient chunks of call to the query and queryMore methods.

Using both the option developer can check the heap memory, using the 1st option heap size will be considerably more then 2nd option, So to avoid heap size limit error developer should always use a SOQL for loop to process query results that returns many records.

Querying Large Data Sets – 
The total number of records that can be returned by SOQL queries in a request is 50,000. If returning a large set of queries causes you to exceed your heap limit, then a SOQL query for loop must be used instead. It can process multiple batches of records through the use of internal calls to query and queryMore.