Thursday, October 4, 2018

Lightning Component Basics: Lightning Component Framework

In this blog, I am going to provide basic overview of lightning component framework.

Lightning component framework is being referred as MVCC modal.

  • Modal
  • View
  • Client-Side Controller
  • Server-Side Controller
In lightning components, Lightning bundle which contains component markup, controller.js (client-side), helper.js (for utility or reusable code) etc acts as primary interface and from client side controller, we can perform server side calls(apex class method invocations).

All calls from Lightning components to server are asynchronous call and we capture the response using callback function.

Below diagram will help you to understand Lightning component framework:


Hope this will help!!!

More Blogs:



Saturday, September 29, 2018

Lightning Components Basics : Considerations while calling server-side controller actions

In this blog, we will cover how to call apex class method from Lightning component and different considerations that we need to consider while performing server side call. Actually all calls to server for apex class routed through controller.js function. From lightning component, you can call controller.js function from where you can call apex method.

First of all in order to associate an apex class with lightning component, you have to specify apex class name in controller attribute.

Also remember that all apex methods or apex member variables needs to annotated with @AuraEnabled.

Below is sample apex class which will be called from lightning:

public class SK_LightningBasicsSSController {
    @AuraEnabled
    public static List<Account> findRecentAccounts(){
        return [select id,name,type from Account 
                order by LastmodifiedDate DESC Limit 10];
    }
}

In order to associated this class with lightning component, use below syntax:

<aura:component controller="SK_LightningBasicsSSController">
    <!-- you code-->
</aura:component>

Now we will call apex method on load of lightning component and will display returned list of accounts.

Below is process to call apex method from controller.js

//Create instance of apex method by using c. annotation followed by method name.
var actionName= component.get("c.findRecentAccounts");
//Specify the callback function as all calls are asynchronous. this callback will be invoked once //response is returned by apex class
actionName.setCallback(this, function(response) {
var state = response.getState();
 //Check response state for SUCCESS and ERROR
if (state === "SUCCESS") {
  //store the response in variable
var apexResponse=response.getReturnValue();
console.log('***'+JSON.stringify(apexResponse));
                //set response to attribute value
component.set("v.ltngAccountList",apexResponse);
}else if(state === "ERROR"){
var errors = response.getError();
console.error(errors);
alert('Problem with connection. Contact your system administrator.');
}
});
//do not forget to add below line as this put this request in queue for asynchronous call
$A.enqueueAction(actionName);

Below is complete code snippet:



Important Points to remember:

How to call apex method which contains parameters


If you have method defined with some parameter, for example search string to search account as mentioned below:

@AuraEnabled
Public static List<Account> SearchAccounts(string searchString){
       //your logic
}

So in order to pass parameters to apex class method, create a JSON as mentioned below:
Suppose you have an attribute defined to take input from user say AccName:

<aura:attribute name="AccName" type="string"/>

var actionName= component.get("c.SearchAccounts");
var params = {
                         "searchString" :component.get("v.AccName")
                      };
actionName.setParams(params);

Note:
  • While creating JSON for parameters, key Value should be similar to parameter name in apex method. In our case the apex method parameter name was "searchString" so while creating JSON we specified first key Value as "searchString".
  • If you have multiple parameters, then create JSON as mention below:
          var params ={
                                 "param1":"param value1",
                                 "param2": "param value2",
                                 "param3": "param value3"
                               };

Create helper function which can be reused for different apex method calls

Instead of writing same piece of code to call different apex methods, we can write function in helper.js which can be invoked from controller.js function by passing the parameters to it.

I have created a helper function which takes 4 parameters:
  • Component reference
  • apex class method name
  • callback function name
  • param (to specify parameters if apex method expect some parameters or arguments)
Below is helper function "callToServer"

({
callToServer : function(component, method, callback, params) {
        var action = component.get(method);
        if(params){
            action.setParams(params);
        }
        console.log('****param to controller:'+JSON.stringify(params));
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                callback.call(this,response.getReturnValue());
            }else if(state === "ERROR"){
                var errors = response.getError();
                console.error(errors);
                alert('Problem with connection.'+errors);
            }
        });
        $A.enqueueAction(action);
    }
})

Now if you have to call apex class method from controller.js then use below syntax:

({
    doInit : function(component, event, helper) {
        var params = {
                                 "searchString" :component.get("v.AccName")
                              };
        helper.callToServer(
            component,
            "c.SearchAccounts",
            function(response)
            {
                console.log('apex response :'+JSON.stringify(response));
                component.set("v.ltngAccountList",response);
            }, 
            params
        );
    }
})

How to call different apex methods in sequential order

All calls to apex methods are asynchronous so if there is need to first call a apex method and based on response call another apex method, then you need to make sure that you perform second call to server after getting the response from first function.
So always perform second call to server from inside the callback function which get invoked when asynchronous call finished on server. 

If you use helper function approach to call apex methods then you can use below syntax to call 2 different (searchAccounts and findAccountdetailsapex method in sequential order.

var param1= {
                         "searchString" :component.get("v.AccName")
                     };
helper.callToServer(
component,
"c.SearchAccounts",
function(response)
{
component.set("v.ltngAccountList",response);
var selectedId = response[0].id;
var param2 = {
"ltngAccId": selectedId
}
//creating component dynamically using helper function
helper.callToServer(
component,
"c.findAccountdetails",
function(response)
{
   //your logic
},
param2
);
}, 
param1
);

Use Wrapper to get all data in single call

Avoid multiple calls to server in order to fetch information as it will degrade the performance.
Use wrapper (user defined data types) to return complete information in single server call.


Hope this will help!!!


Friday, September 28, 2018

Lightning Components Basics : Handling Actions in Controller.js

Lightning component bundle comes with different resources like controller.js, helper.js, style.css etc.

All the actions performed on lightning component, can be handled in controller.js.
helper.js worked as an utility which can be called multiple times. If you want to call same piece of code multiple times, then specify it as separate reusable function in helper.js and call it from controller.

I have created a sample lightning component "SK_LightningBasics". Below is code for that:

SK_LightningBasics.cmp

<aura:component >
    <aura:attribute name="ltngFirstname" type="string" default="Sunil"/>
    <aura:attribute name="ltngLastname" type="string" default="Kumar"/>
    <!--Mark up starts-->
    <lightning:input aura:id="userFn" value="{!v.ltngFirstname}" name="ufn" label="Firstname"/>
    <lightning:input aura:id="userLn" value="{!v.ltngLastname}" name="uiln" label="Lastname"/>
    <lightning:input aura:id="useremail" value="" name="uinput" label="Enter Email"/>
    <lightning:button name="btn" label="Display" onclick="{!c.displayMessage}"/>
    <!--Mark up ends-->
</aura:component>

SK_LightningBasicsController.js

({
displayMessage : function(component, event, helper) {
             var fname= component.get("v.ltngFirstname");
             var lname= component.get("v.ltngLastname");
             //how to get input by user 
             //which is not related to attribute
             var emailInputTag= component.find("useremail");
             //Now you can refer any attribute on input tag
            var emailvalue= emailInputTag.get("v.value");
            console.log('*******emailvalue-'+emailvalue);
            //to find label for email input
            var emailLabel= emailInputTag.get("v.label");
            console.log('*******emailLabel-'+emailLabel);
            var alertMsg='displayMessage function get called.\n';
           alertMsg = alertMsg +'Email entered is -'+emailvalue;
           alert(alertMsg);
    }
})

Lightning is based on MVCC (Modal-View-Client side controller-Server side controller), so first functions defined in controller.js is called first and then if needed we can call server side apex class methods.

In above lightning components, we are using onclick attribute on lightning button which invokes controller.js function.

In lightning, we refer controller.js functions using c.annotation inside "{! and }".
For example{!c.displayMessage}

Way to invoke controller.js function when component loaded initially

Lightning framework provide standard events which can be used to invoke controller.js function.
Use below syntax to invoke controller.js function when component is getting loaded:

<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

Specify the controller.js function which you want to invoke. By using above code snippet, we are calling doInit function in controller.js.

({
doInit: function(component, event, helper) {
             alert(' doInit get called');
      },
      displayMessage : function(component, event, helper) {
             //your logic
      } 
})

Way to invoke controller.js function when any attribute value gets changed

Use change event on attribute to invoke controller.js function.

Sample code snippet:

<aura:attribute name="ltngFn" type="string" default="Sunil"/>
<aura:handler name="change" value="{!v.ltngFn}" action="{!c.OnChangeFunction}"/>

So whenever "ltngFn" attribute value will be changed then, OnChangeFunction will be invoked

({
doInit: function(component, event, helper) {
             alert(' doInit get called');
      },
      displayMessage : function(component, event, helper) {
             //your logic
      },
      OnChangeFunction: function(component, event, helper) {
             alert(' Attribute value gets changed');
      } 
})

In order to test these component code, you can either create lightning tab or create lightning app and preview it. Below is code for lightning app:

SK_LightningBasicsApp.app

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

</aura:application>

After creating this app, click on preview button on top right side in developer console.

Hope this will help!!


Saturday, September 22, 2018

Lightning Components Basics : Attributes, Expressions and Value Providers

Attributes
Attributes are just like apex class member variables which holds some value and can be used in performing any operation.
Same like apex class member variable, you need to define name of attribute, datatype of attribute and you can also define default value which is optional.
Below is syntax to define attribute:

        <aura:attribute name="firstname" type="string" default="Sunil"/>

Other attributes are:
  • access- Indicates whether the attribute can be used outside of its own namespace. Possible values are public (default), and global, and private.
  • required - If it is required to specify the value of attribute. The default is false.
  • description - Specify the purpose and usuage of attribute.
Supported values for type are Boolean, date, datetime, decimal, double, integer, long, string, collections (list,set,map), standard and custom objects and user defined data types(wrapper class).

Please refer below URL for more information on basic data types:

Component Attributes Types
                                   
Note:
Salesforce recommend using type="Map" instead of type="Object" to avoid some deserialization issues on the server. For example, when an attribute of type="Object" is serialized to the server, everything is converted to a string. Deep expressions, such as v.data.property can throw an exception when they are evaluated as a string on the server. Using type="Map" avoids
these exceptions for deep expressions, and other deserialization issues.

Checking for Types
To determine a variable type, use "typeof" or a standard JavaScript method instead. The "instanceof" operator is unreliable due to the potential presence of multiple windows or frames.

Expression

Expression are kind of formula which can be used within expression delimiters (“{!” and “}”)in expressions, you can specify attributes or different operators to give you output.

          <aura:attribute name="msg" type="String"/>  
            <p>{!'Hello! ' + v.msg}</p>

Value Providers

Value providers helps you to access attributes values and you can use them either in component markup or in JavaScript functions. Using value providers, you can either set or get attributes values.

        <aura:attribute name="msg" type="String"/>  
            <p>{!'Hello! ' + v.msg}</p>

  • Way to find attribute value in controller.js:

               var msgValue = component.get("v.msg")

  • How to set attribute value in controller.js

              component.set("v.msg","Sunil Kumar");

Friday, September 14, 2018

Lightning Component For Timer

I have created a lightning component to display timer. This is useful when you want to display timer to end user so that he/she can understand remaining time.

This component can be used if you are planning to create time tracking app or online exam screen.


Below is complete code snapshot:

Hope this will help!!

Lightning Component for Stopwatch

I have created a lightning component which can work as stopwatch and will display time in "hh:mm:ss" format.



Below is complete code for this lightning component:

Hope this will help!!

Monday, September 3, 2018

lightning:isUrlAddressable Interface: Way to get URL parameters in Lightning Components

In Summer'18 release, Salesforce introduces new interface for lightning components which can be used to fetch URL parameters in lightning components.

Before this, we have to write logic in controller.js function to get current URL and split the url parameters.

If we are using lightning tab and displaying lightning component, then we can fetch URL param by using "{!v.PageReference.state.xxxxx}" where xxxxx is URL parameter name.

I have created a lightning component "SK_URLParamCmp.cmp" in order to explain the usage of this interface. Below is code snapshot:

Now I have created a lightning tab "SK_URLParam_Tab", which will open this lightning component.  Pass any value in URL as "accname" as parameter. Below is sample URL:

"/lightning/n/SK_URLParam_Tab?accname=sunil"

Below is UI snapshot:


Hope this will help!!

Note:

If changes to lightning Components are not reflecting immediately in lightning tabs, then you have to disable the "Enable secure and persistent browser caching to improve performance" option under Caching section in Session settings.

For more details on this setting, please refer below URL:
Improved Performance with Secure Client-Side Caching

Friday, August 24, 2018

Way to get list of Scheduled reports and Jobs from Salesforce

This is very common ask from business admins or end users to get list of schedule reports or schedule jobs (batch jobs, scheduled jobs etc) from Salesforce.

There is no standard view provided by Salesforce to view list of scheduled reports or reports. Users have to navigate to Monitor section under SetUp.


This section display list of jobs either schedule or completed jobs but does not provide complete list of jobs.

By using apex, you get the list of schedule reports or jobs in csv format via email. 

Please find below the apex code for that:


Now if you have to get list of scheduled reports in your org, then just execute below script in developer console:

  • For getting list of scheduled reports:         SK_ScheduleJobUtility.findScheduledJobDetails('Report Run');

  • For getting list of scheduled batch jobs:         SK_ScheduleJobUtility.findScheduledJobDetails('Batch Job');

  • For getting list of scheduled apex jobs:        SK_ScheduleJobUtility.findScheduledJobDetails('Scheduled Apex');


Important Use case

Sometime reports are scheduled by user which becomes inactive, then all system admin start getting email saying:

"The user account that runs the report (the running user) is inactive."

This utility will send email along with user details which will help in identifying all inactive user for whom reports are scheduled as running user.


Hope this will help!!

Looking forward for everyone's comments and feedback.

Monday, August 20, 2018

Creating Lightning Components Dynamically

Through this blog, I will share the approach to create lightning components dynamically by sharing an example in which we will display account summary information by creating summary component dynamically.

I have already posted one blog through which we can create ui:button dynamically and can destroy it. Please refer below URL if you want to refer that before continuing with this blog:

creating or destroying buttons dynamically

Below is snapshot of app which will display recent accounts on left side and on right side, it will display opportunities and case summary for account. You can click on "show Info" link before any account record and its related information will appear on right side dynamically.


Code to create dynamic component

You can use $A.createComponent method which accepts 3 parameters:
  1. ComponentName (String) :Type of component to create like "c:newCmp" etc.
  2. attributes : JSON specify component attributes values
  3. callback function: Once the component is created, this callback function will be invoked.This function can be used to append newly created component to target component. You can place the newly created component inside some div to display.
Below is sample code along with comments to explain steps:

 //find the div markup where you want to display dynamic component
//here "dynamicCmpSection" is aura:id of div
var targetCmp = component.find("dynamicCmpSection");
//create JSON specify all attributes needed for new component
var cmpAttributes = {
                "attribute1": "attribute Value",
"attribute1": "attribute Value"
            }
$A.createComponent(
"c:Demo_DynamicViewCmp", 
cmpAttributes,
function(tempbody) {
//Check if component is valid
if (component.isValid()) {
var targetCmp = component.find("dynamicCmpSection");
//first remove all content inside the div by making its body as null
targetCmp.set("v.body",[]);
var body = targetCmp.get("v.body");
//add newly created component in div
body.push(tempbody);
targetCmp.set("v.body", body);
console.log('***component loaded successfully');
}
}
);

Below is complete code related to snapshot shown in blog.

Hope this Helps!!

Sunday, August 19, 2018

Application Events : Way to Communicate Between Different Lightning Components

Application events are used to communicate between different lightning components. These are different from component events as these are not dependent on containment hierarchy.

Application events behaves similar to standard events. There is no need to register for application event by any component. Any component can fire application event where as in component events, components have to register first in order to fire that event.

Through this blog, I will explain different aspect of using application events:

I have created a lightning app which contains 2 separate components. User is entering some information and sending it to second component by clicking on button.



Below are different steps you need to follow in order to implement application events:

  • Create lightning event "SK_MessagerEvent" of type Application
       <aura:event type="APPLICATION" description="Event template" >    
            <aura:attribute name="msg" type="String" access="GLOBAL"/>                           
       </aura:event>

  • Use below syntax to fire event from lightning component:
        var appEvent = $A.get("e.c:SK_MessengerEvent");
        appEvent.setParams({"msg":component.get("v.ltngUserInput")}); 
        appEvent.fire();

  • Create handler in component which want to consume or catch the information passed using application events.
       <aura:handler action="{!c.handleNotification}" event="c:SK_MessengerEvent" />
  • Create function in controller.js which will get invoked whenever this application event will be fired.
        var sentMessage= event.getParam("msg"); 
        console.log('******sentMessage by app event:'+sentMessage);
        component.set("v.recMsg",sentMessage);

Below is complete code for your reference related to snapshot shown above:


Hope this help!!

More Blogs>>: 
COMPONENT EVENTS: Communicate Between Components in Containment Hierarchy    
INHERITANCE IN LIGHTNING    
FIRING EVENT FROM LIGHTNING COMPONENT AND PASSING IT TO VF PAGE    
CHANGES TO LIGHTNING DATA SERVICE IN SUMMER'17    
LIGHTNING DATA SERVICES    
PASSING LIGHTNING COMPONENT ATTRIBUTE VALUE FROM VF PAGE    
FIRE LIGHTNING EVENTS FROM VF PAGE    
DYNAMICALLY CREATING AND DESTROYING LIGHTNING COMPONENTS    
RAISING AND HANDLING CUSTOM EVENTS IN SALESFORCE LIGHTNING    
WHY TO USE DESIGN RESOURCE AND HOW TO ADD DYNAMIC OPTION TO DATASOURCE    
PASSING LIGHTNING COMPONENT ATTRIBUTE VALUE FROM VF PAGE    
PASSING INNER WRAPPER CLASS TO LIGHTNING COMPONENT    
LIGHTNING COMPONENT FOR RECORDTYPE SELECTION FOR ANY SOBJECT    
CUSTOM COMPONENT TO SHOW/HIDE SPINNER IMAGE    

Monday, August 13, 2018

Component Events: Way to Communicate Between Components in Containment Hierarchy

Components events can be used to pass information between lightning components which are in containment hierarchy. Component events can be handled by component which is firing it or by component container.

Through this blog, I am going to explain how to utilize component events with sample code.


I have created a sample lightning app which contains "c:SK_MasterCmp".  "c:SK_MasterCmp" contains another component "c:SK_ChildCmp"

Below are steps which you need to follow while utilizing component events:

  • Create Lightning event of type "COMPONENT".
        <aura:event type="COMPONENT" description="Event template" >
              <aura:attribute name="passedValue" type="string"/>
        </aura:event>

  • Register the component event which is going to fire component event.
        <aura:registerEvent name="changeValueEvent" type="c:SK_LightningEventChannel"/>
  • Use below syntax to fire event and pass information from "c:ChildCmp".
        var newEvent = component.getEvent("changeValueEvent"); 
        newEvent.setParams({"passedValue":"twitter handle-@sunil02kumar"});                               
        newEvent.fire();
  • Create handler in component which needs to handle the events means want to consume that information. Note the name of handler should be same as that while registering event:
       <!--name should be equal to name while register event-->
       <aura:handler name="changeValueEvent" event="c:SK_LightningEventChannel" 
                  action="{!c.handleNotification}"/>
  • Create function in controller.js which will be called when "c:MasterCmp" will handle the the event.
       handleNotification : function(component, event, helper){
           console.log('****handling event');
           var sentMessage= event.getParam("passedValue");
           component.set("v.mastervalue", sentMessage);
      }


Below is complete code for reference:



Hope this help!!

Thursday, August 9, 2018

How to get User Session Id in Future Method or Batch Class

Sometime it is required to perform Callout in future method and Batch apex class. If we use UserInfo.getsessionId() method inside the future method or batch apex, then it will return null.

Below are different option to get sessionId:

Option 1:

We can either pass sessionId as parameter to future method or to batch apex class.

Option 2:

Create a VF page and use {!$Api.Session_ID} in body.  In apex, get VF page content which will contain session Id.

Below is code snippet explaining the Option 2 by using future method. Same can be used in Batch Apex.

Run below code snippet in execute anonymous to check the output in debug logs:

SessionIdUtility.checkIfUserSessionIdExistInFutureCall();



Hope this help!!!

Remote Site Settings : Way to Create/Update Using Apex (Metadata API)

We can create or update Remote Site Settings in Apex using Metadata API.

You can either download Metadata API WSDL from Salesforce and generate apex class by clicking on Generate from WSDL button.


Or you can download the MetadataService class from below link:

MetadataService.cls

Below is sample to code to create remote site settings.


Execute this static method from execute anonymous and check if records created or not.

 MetadataAPIUtility.createRemoteSiteSettings();

Below is snapshot of remote site settings created


Note:
  • I have used upsertMetadata method. If you want to only insert new remote site setting, then use insertMetadata method
  • fullname property is considered in order to decide whether remote site setting needs to be created or updated.
Hope this will help!!!


Create Custom Metadata Types Using Metadata API
Create Update Custom Label by Using Metadata API


Thursday, July 26, 2018

How to Schedule Apex class to Run Instantly or Run After Some Duration from Developer Console

We create apex scheduler job which can be scheduled to run at specific time. If we want to run job instantly to either check the functionality or want to force start scheduled job then below code sample will help you.

Suppose you have scheduled apex class:

global class SK_JobsSchedulerHelper implements Schedulable {
global SK_JobsSchedulerHelper(){

}
       global void execute(SchedulableContext sc) {
//your business logic
}
}

Now if you want to run it instantly from developer console, then use below script:

SR_JobsSchedulerHelper sch = new SR_JobsSchedulerHelper();
sch.execute(null);

Now if you want to run this job after 5 minutes, then you can use below script:

SR_JobsSchedulerHelper sch = new SR_JobsSchedulerHelper();
Datetime dt = Datetime.now().addMinutes(5);  
String schCronExp = dt.format('s m H d M \'?\' yyyy');
Id schedId = System.Schedule(' scheduling this job at'+System.now().format(),schCronExp,sch);

Hope this help!!


Thursday, July 12, 2018

Adding Lightning Components in VF Page and Passing Values from URL

Can we create custom lightning components and use them in Salesforce Classic?

This question always comes in mind whenever we do development in Org which has not enabled lightning. We call these kind of Org as classic Salesforce Org.

We mainly create lightning components and use them in Lightning experience but it doesn't means that we can not utilize lightning components in Classic Salesforce (in VF)

If we have to create VF page, then create lightning components as per requirement and then add them in VF pages. So if in future, you migrate to Lightning from Salesforce Classic then you do not have to re-work on implementing VF functionality in Lightning.

Through this blog, I am going share sample code which explains how we can create lightning components and add it to VF pages. As lightning components works mainly based on attributes defined in component, how we can pass values to these attributes from VF page so that they behave as per requirement.

In below code, I am passing the Account Id and string message in VF page using URL parameters and then sending Account name and message to lightning component.

You can open VF page and specify parameters in URL. Below is sample URL:

/apex/SK_LtngCmpContainerVF?id=0019000001rHOgA&infoString=AccountId is passed from URL in VF and captured by component

or

/apex/SK_LtngCmpContainerVF?id=0019000001rHOgA&infoString=AccountId%20is%20passed%20from%20URL%20in%20VF%20and%20captured%20by%20component

Below is screenshot of VF page

Hope this will help!!!

Sunday, July 8, 2018

Create Custom Metadata Types Using Metadata API

As we know, custom metadata is also considered as metadata due to which it helps to migrate predefined settings between different Organizations. If we use custom setting, then we need to upload custom records separately after migrating custom settings.

By using, Metadata API we can create apex script to create custom metadata.

You can either download Metadata API WSDL from Salesforce and generate apex class by clicking on Generate from WSDL button.


Or you can download the MetadataService class from below link:

MetadataService.cls

Below is custom metadata created for explaining the apex code:



Below is code snippet to create custom metadata record.


Execute this static method from execute anonymous and check if records created or not.

 MetadataAPICMUtility.createCustomMetadata();

Below is snapshot of record created


You can use above code sample to create records in custom metadata. You can maintain .csv file with all custom metadata records and parse it with apex and then create record in custom metadata.

In order to understand when to use custom setting or custom metadata type and their implementation tricks, please refer below URL:

Custom Metadata Types and Custom Settings Implementation Tricks


Hope this will Help!!!

Wednesday, July 4, 2018

Create Update Custom Label by Using Metadata API

We usually update custom labels from UI. After sandbox refresh, we update all custom labels so that these don't point to production URLs or values.

By using Metadata API, we can write automated apex script through which we can update all custom labels.

You can either download Metadata API WSDL from Salesforce and generate apex class by clicking on Generate from WSDL button.


Or you can download the MetadataService class from below link:

MetadataService.cls

I have created 2 separate static methods, one for creating new custom label and another for updating existing custom label. Below is class code:


Now by running below code in execute anonymous in developer console, you can create custom label:

MetadataAPIUtility.createCustomLabel('SFDC_Blog_URL','My test label from metadata api','en_US','http://www.sfdcstuff.com/',false);



You have to specify custom label values as a parameters in static method.

In order to update custom label, execute below code:

MetadataAPIUtility.updateCustomLabel('SFDC_Blog_URL','My test label from metadata api','en_US','https://www.sfdcstuff.com/search/label/Lightning',false);



Hope this will help!!




Monday, June 18, 2018

Search Content on Box from Salesforce Using Content Search API

In this blog, I am going to share the code snippet which can be used to do callout from Apex in order to search content on Box. You need to have access token in order to perform this callout.

To learn how to get access token from box, please refer Box and Salesforce Integration

Box provide content search API through which you can search for files and folders present in Box.
I have created a wrapper class in apex which will be used to parse the JSON response from Box.

Below is code snippet:

You can call this static method and pass the parameters to get results.

Hope this will help!!

Friday, June 1, 2018

Alternatives to OnClick Javascript buttons : Way to replace OnClick Javascript buttons across all objects with Single VF page

We always prefer onclick javascript button to perform different operations like updating fields on same records or on other records with single click by user. In order to do this, we either use ajax toolkit to either perform logic or to call apex method.

We can also perform these operation even by redirecting user to VF page on click of button and call apex method on VF page load (by specifying action attribute on <apex:page>) and redirecting User back to record details page.

Developers usually not use this approach as they do not want to create new VF page every time for these kind of requirements.

After the launch of lightning, onclick javascript buttons are not recommended and everyone is finding alternative for onclick javascript buttons functionality but sometime these alternative results in more than 1 click for end user.

Through this blog, I just to share one approach through which we can utilize single VF for all custom buttons. We just need to pass recordId and apex class name which contains your logic for operation in URL. This approach also involves single click from user and user will get notified about success and failure of operation (in onclick javascript we user alert to notify).

Different steps involved for this approach:
  • Create a VF page and controller. Create wrapper in this controller to store redirect url (to redirect user after performing operation), success and failure message which you want to display to user.
  • Create an Interface with method name executeLogic (return type will be wrapper of VF controller).
  • Create a new apex class which implements interface and will contain logic in executeLogic method.
  • Create a custom button and specify URL. pass recordid and apex class name where you have written your logic.

Sample Requirement:

I need to create a custom button on Account. When user click on that, I need to check if billing country and billing postalcode in not blank, then change the type field to 'Prospect'.

Traditional Approach:

Create a onclick Javascript button and call apex method from that to perform operation. Dispaly success/error message using alerts.

New Approach:

Below are code related to new approach:

Now create custom button on Account as mentioned in below image

URL will be like:

/apex/OnClickJSUtilityVF?rid={!Account.Id}&cname=AccountUtility

here "AccountUtility" is apex class name which contain logic.

If we use this approach then, going forward we just need to create apex class with method and implement the interface.

If we consider the both approaches, the amount of code that we need to write for any new custom button functionality will remain same.

Demo snapshots:

When I click on Change to Prospect button with billing country and billing postal code as blank, getting below message:

When clicking on Change to Prospect button after specifying values for billing country and postal code, getting below message:

These success and error message are specified in apex method in apex class. So you can specify different message based on different requirements.

Also you can specify the redirect URL in apex method where user will navigate after performing the requested action.

You can style your VF page as per your org need and all users will have same user experience.

Hope this will help!!!

Looking forward for everyone comments and suggestions.

Sunday, May 20, 2018

Adding button and sorting columns in Lightning DataTable

Salesforce has launched Lightning:Datatable tag to display list of records in lightning components.

In this blog, I will share the code through which we can add a button in column and call javascript controller function on click of that button. Also I will share the code required to enable sorting on columns for datatable.

Use case: Display list of account records along with view button and onclick of that button call javascript controller function. Once the javascript controller function is invoked, you can open any other component or redirect user to account detail page as per requirement.

In order to add button, you have to specify input type as button and provide type attributes while specifying the columns.

{
label: 'Action',
type: 'button',
typeAttributes: {
iconName: 'utility:view',
label: 'View Record',
name: 'viewRecord',
disabled: false,
value: 'viewBtn'
}
}

you can use onrowaction event on lightning:datatable to call javascript controller function.

Below is sample code which includes sorting as well as button in one of the columns:


Below is snapshot:

Click here for  Lightning DataTable Demo .

Hope this will help!!!


Sunday, April 15, 2018

Data Architecture and Management Designer : Things to consider before appearing for this exam

Today is very special day for me as I have completed my Application Architect exam by completing second exam (Data Architecture and Management Designer) on Architect journey and this is my 100th blog on Salesforce.

I would like say big thanks to Salesforce community who motivated for this and provided their support to achieve this.



Through this blog, I am going share my preparation experience and tips for everyone who all are planning for this.
  • For self study, please refer Resource Guide for Data architecture and management designer, which contains all the study material links for different topics. If you complete this, then you are ready for this exam. 
  • Development knowledge is not necessary for this exam but if you have development experience then you can easily understand Large Data Volume considerations easily.
  • Exam contains lot of scenario based question. Most of question are like which decision or step you will take for given problem being Data Architect.
  • Different ways of maintaining data quality.

Below are different topics which you need to cover for exam. Also I have accumulated below information from different source in place for quick overview.
  • Duplicate Management
Please go through matching rules and Duplicate rules and how to configure them
Different option which you configure when duplicate detected(Alert, Block, reporting etc)
  • Data Archiving and Purging
There were many question on for specific scenarios how to implement data archiving. Also cover on which case, we should use ETL tools.

Different points to remember:
    1. Aggregate info on parent object and delete child object if reporting is required only in parent info.
    2. Always plan for data archiving and purging as data keeps on increasing with time.
    3. Records in recycle bin also affects query performance so if you don't want records, then perform hard delete.
  • MDM Solution
When you have different application and different data stored in different application for customers, then implement MDM solution to have single source of truth for records. 
  • PK Chunking
You can use PK Chunking with most standard objects and all custom objects.

To enable the feature you specify the header ‘Sforce-Enable-PKChunking‘ on the job request for your Bulk API query.

                           Sforce-Enable-PKChunking: 

By default the Bulk API will split the query into 100,000 record chunks – you can use the ‘chunkSize‘header field to configure smaller chunks or larger ones up to 250,000. Larger chunk sizes will use up fewer Bulk API batches, but may not perform as well. For each object you are extracting, you might need to experiment a bit to determine the optimal chunk size.

                       Sforce-Enable-PKChunking: chunkSize=250000;

You can perform filtering while using PK Chunking by simply including a WHERE clause in the Bulk API query. In this case, there may be fewer records returned for a chunk than the number you have specified in ‘chunkSize‘. 

If an object is supported, you can also use PK Chunking to query the object’s sharing table. In this case, determining the chunks is more efficient if the boundaries are defined on the parent object record IDs, rather than the share table record IDs. To take advantage of this, you should set the value of the Parent header field to the name of the parent object. For example, when querying OpportunityShare, set Parent to Opportunity.

For example:
Customer is planning a security audit and wants to identify all the manual shares that exist on their Account records. To execute this, they can perform a bulk query on AccountShare, using the filter WHERE rowCause=Manual, with a header like this: 

                   Sforce-Enable-PKChunking: chunkSize=250000; parent=Account 
  • Data Governance & Data Stewardship
Data governance includes what type of information is required, who can create it and update it and specify quality rules(data  integrity, usability and security)

Data Stewardship includes how to maintain data and its distribution to its users.
  • Skinny Tables
You can refer this blog for Skinny Tables Overview
  • Bulk API
Cover different scenario on when to use parallel mode or serial mode for Bulk API.
If you are getting lock contention errors, then load child records order by parent record Id.
If you getting group membership locks, then use serial mode for Bulk API.
Lock contention errors may occur if you have master detail, lookup relationship and roll up summary fields defined.
Avoid full relaod operations as it will consume more resource. Try to perform incremental upload.

Please refer LDV Best practices link. It covers most of the topics for this exam.

Problem Statements

Slow report on a large object 
  • Document your org’s indexed fields.
  • Learn index selectivity rules.
  • Build reports that use indexes.
  • Don’t use formula fields (returning non-deterministic values) in filter as they are calculated on fly which will reduced the performance
 
Slow bulk data load 
  • Cleanse and transform data pre-load.
  • Disable triggers, validations, assignment rules,and workflow rules pre-load.
  • Use the Bulk API.
  • Keep a Full Queue : The Force.com platform cannot process what it doesn’t have the opportunity to process, and slowly feeding batches and jobs to Salesforce causes platform threads to sit idle when they could be processing batches. Always try to keep at least 20 batches on the queue at any given time. 

Lock contention problems while data load
  • Pre-sorting the child records by parent Id in CSV file to lessen the chance of parent record lock contention among parallel load batches
  • By deferring the org’s sharing calculations until data load finish, could significantly increase both the load and sharing calculation performance.
  • For optional lookup fields, you can avoid the locks by setting the Clear the value of this field option, which does more than just tell Salesforce what to do if your lookup record is deleted. When you set this option, whenever a record that has a lookup field to this lookup record is inserted or updated, Salesforce doesn't lock the lookup records; instead it only validates that the lookup values exist.
  • Roll Up Summary Fields : Salesforce locks those master records so it can update the appropriate roll-up summary field values. If detail records that look up to the same master record are updated simultaneously in separate batches, and those updates affect roll-up summary fields on the master record, there is a high risk that these updates will cause lock exceptions.
  • Disable triggers and Workflow rules to improve performance. Whenever trigger perform DML on other records of object then salesforce lock those records which may cause lock contention errors in parallel load. When workflow update fields then it lock the records which can result in lock contention errors.
  • Group Membership Locks: For a few special operations, Salesforce uses organization-wide group membership locks. To avoid lock exceptions when performing the following operations, you must use serial processing for your data load. 
    1. Adding users who are assigned to roles 
    2. Changing users’ roles 
    3. Adding a role to the role hierarchy or a territory to the territory hierarchy 
    4. Changing the structure of the role hierarchy or the territory hierarchy 
    5. Adding or removing members from public or personal groups, roles, territories, or queues 
    6. Changing the owner of an account that has at least one community role or portal role associated with it to a new owner who is assigned to a different role than the original owner
Full Database Backups are Slow
  • Perform incremental data backups–only backing up the data that is new or updated since the previous incremental backup. When doing this, use queries that filter records using SystemModstamp (a standard field in all objects that has an index) rather than LastModifiedDate field (not indexed).
When to use serial load option rather than parallel?
  • When you insert group members or users who are assigned to roles—or perform any other data load that requires group membership operations—Salesforce uses organization-wide group membership locks to ensure data integrity and security.
  • If you are not able to manage or avoid lock contention errors then switch to serial mode for data load.

What are Strategies for Addressing Lags in Search Indexing?

Depending on the current load and utilization of indexing servers, asynchronous text index updates may lag behind actual transactions. This lag means that stale search indexes can lead to search results not entirely representative of the current database records.

The amount of time necessary to update search indexes is directly related to the amount of text data that such loads modify, and can be quite lengthy in some cases.
So how can you architect acceptable solutions that address inevitable lags in search indexing after data loads? Here are a couple of things to consider.
  1. Disable full-text search indexing for custom objects (especially large ones) that don’t need to be searchable. 
  2. Instead of relying on the full-text search engine and SOSL, implement your application’s search feature using SOQL. Because SOQL queries target the transactional database, they’ll always return results that correspond to the latest set of committed records.

Hope this will help!!!