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.

Advertisements

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;
}