Use Lightning Component in Visualforce Page

In Winter’16 the ability to add Lightning Components to Visualforce pages was made generally available. This powerful new feature allows you to reuse existing Lightning Components or design and implement new features as Lightning Components with the flexibility to use of them in new or existing Visualforce pages.

This article is to show you how to add Lightning components to Visualforce pages.

Let’s create a lightning component named “HelloWorld.cmp” either through developer console or through your IDE. Use the below mentioned code in your lightning component.

Lightning Component:

<!--HelloWorld-->
<aura:component implements="force:appHostable">
    <div>
        Hello World    
    </div>
</aura:component>

Now we use this Lightning component in a Lightning app. For this I recommend you to create a new Lightning app, let’s call it “HelloWorldApp.app” and use the above lightning component “HelloWorld.cmp” in this app.

Lightning App:

<!--HelloWorldApp-->
<aura:application extends="ltng:outApp" access="global">
    <aura:dependency resource="c:HelloWorld"/>
</aura:application>

In above Lightning app, I have used aura application access as global, so that it can be used anywhere in Salesforce organization like Visualforce. Extending ltng:outApp indicates that any component defined in this application can be used on Visualforce page.

Now create a VisualForce page which would display this lightning component. VisualForce page would provide the interface where we can view the lightning component that we are going to use in the page. Use the below code in your VF page.

In my Visualforce page, we have a special include apex:includeLightning for Lighting. We also need to create a container div id="LightningContainer" for the Lightning components to appear in.

Visualforce Page:

<apex:page >
    <apex:includeLightning />
    <div style="width:100%;height:100px;" id="LightningContainer" />
    
    <script>
        $Lightning.use("c:HelloWorldApp", function() {
            $Lightning.createComponent("c:HelloWorld", { },
            "LightningContainer",
            function(cmp) {
                console.log('Component created');
            });
        });
    </script>
</apex:page>

Note: If your Org has a namespace, then in Visualforce page we have to mention the namespace for Lightning app as yournamespace:HelloWorldApp instead of c:HelloWorldApp.

Here is the Visualforce page output:

Call Multiple Apex Methods in Lightning Controller

Apex Controller:

public with sharing class AccountController {

    @AuraEnabled
    public static Account getAccount(Id accountId) {
        Account acc = new Account();
        acc = [SELECT Id, Name, Description FROM Account WHERE Id=:accountId];
        return acc;
    }
    
    @AuraEnabled
    public static List<Attachment> getAttachments(Id parentId) {                            
        List<Attachment> listAttachment = new List<Attachment>();
        listAttachment = [SELECT Id, Name FROM Attachment WHERE ParentId = :parentId];
        return listAttachment;
    }
}

Lightning Component:

<aura:component controller="AccountController" implements="force:appHostable,flexipage:availableForAllPageTypes,force:hasRecordId" access="global">
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="acc" type="Account"/>
    <aura:attribute name="attachments" type="Attachment[]"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    
    <div>
        <div>{!v.acc.Name}</div>
        <div>{!v.acc.Description}</div>
        
        <ul>
            <aura:iteration items="{!v.attachments}" var="a">
                <li>
                    <a target="_blank" href="{! '/servlet/servlet.FileDownload?file=' + a.Id }">{!a.Name}</a>
                </li>
            </aura:iteration>
        </ul>
    </div>

Lightning Controller:

({
    doInit : function (component) {
    var action = component.get('c.getAccount');
    action.setParams({
        "accountId": component.get("v.recordId")
    });
        
	action.setCallback(this, function(response) {
        var state = response.getState();
        if (state == "SUCCESS") {
            var account = response.getReturnValue();
            component.set("v.acc", account);
        }
    });
        
    var action2 = component.get('c.getAttachments');
    action2.setParams({
        "parentId": component.get("v.recordId")
    });
        
	action2.setCallback(this, function(response) {
        var state = response.getState();
        if (state == "SUCCESS") {
            var attachments = response.getReturnValue();
            component.set("v.attachments", attachments);
        }
    });
    $A.enqueueAction(action);
    $A.enqueueAction(action2);
}
})

Enum in Apex

Biswajeet   October 20, 2017   No Comments on Enum in Apex

An enum is an abstract data type with values that each take on exactly one of a finite set of identifiers that you specify. Enums are typically used to define a set of possible values.

Although each value corresponds to a distinct integer value, the enum hides this implementation so that you don’t inadvertently misuse the values, such as using them to perform arithmetic. After you create an enum, variables, method arguments, and return types can be declared of that type. Apex provides built-in enums, such as LoggingLevel, and you can define your own enum.

To define an enum, use the enum keyword in your declaration and use curly braces to demarcate the list of possible values.

For Example:
The following code creates an enum called Season:

public enum Season {WINTER, SPRING, SUMMER, FALL}

By creating the enum Season, you have also created a new data type called Season. You can use this new data type as you might any other data type.

For Example:

Season e = Season.WINTER;

Season CheckSeason(Season e) {
    if (e == Season.SUMMER){
		return e;
	}
} 

Enum Methods:
All Apex enums, whether user-defined enums or built-in enums, have the following common method that takes no arguments.

values : This method returns the values of the Enum as a list of the same Enum type. Each Enum value has the following methods that take no arguments.
name : Returns the name of the Enum item as a String.
ordinal : Returns the position of the item, as an Integer, in the list of Enum values starting with zero.
Note: Enum values cannot have user-defined methods added to them.
For Example:

Integer i = StatusCode.DELETE_FAILED.ordinal();
String s = StatusCode.DELETE_FAILED.name();
List<StatusCode> values = StatusCode.values();

SOQL Statement to Select All Records Even From Recycle Bin

SOQL statements can use the ALL ROWS keywords to query all records in an organization, including deleted records and archived activities.

For Example:

[SELECT COUNT() FROM Contact WHERE AccountId = '0030E00000D34jq' ALL ROWS]

You can use ALL ROWS to query records in your organization’s Recycle Bin. You cannot use the ALL ROWS keywords with the FOR UPDATE keywords.

Lock Records Using Apex in Salesforce

In Apex, to lock records, simply use the FOR UPDATE keyword in your SOQL statements. While an sObject record is locked, no other client or user is allowed to make updates either through code or the Salesforce user interface. The client locking the records can perform logic on the records and make updates with the guarantee that the locked records won’t be changed by another client during the lock period. The lock gets released when the transaction completes.

For example, the following statement, in addition to querying for 5 Account record, also locks the accounts that are returned:

List<Account> accList = [SELECT Id, Name From Account LIMIT 5 FOR UPDATE];


Locking Considerations:

  • While the records are locked by a client, the locking client can modify their field values in the database in the same transaction. Other clients have to wait until the transaction completes and the records are no longer locked before being able to update the same records. Other clients can still query the same records while they’re locked.
  • If you attempt to lock a record currently locked by another client, your process waits for the lock to be released before acquiring a new lock. If the lock isn’t released within 10 seconds, you will get a QueryException. Similarly, if you attempt to update a record currently locked by another client and the lock isn’t released within 10 seconds, you will get a DmlException.
  • If a client attempts to modify a locked record, the update operation might succeed if the lock gets released within a short amount of time after the update call was made. In this case, it is possible that the updates will overwrite those made by the locking client if the second client obtained an old copy of the record. To prevent this from happening, the second client must lock the record first. The locking process returns a fresh copy of the record from the database through the SELECT statement. The second client can use this copy to make new updates.