Tech blog to share information.

April 8, 2019

A curious case of Javascript .apply() and Salesforce ActionFunction.

April 08, 2019 Posted by tjcool , , No comments

A curious case of Javascript .apply() and Salesforce ActionFunction.

Personally, I always like working on javascript. More I explore js, more I learn. And yes it always excites me. This motivates me to learn continuously. On the Same front, I was exploring dynamic function calling in JS. In Salesforce, calling function dynamically is altogether a challenge(only way to do so, is using Type class). We all know we can invoke function dynamically in JS using various way like applybindcall. While exploring .apply() function, I started looking into possible use cases of a .apply(), as I always believe in learning with the use case. We will see, why I was exploring apply.
Who are new to JS or dynamic function invocation, let me give the quick overview. In JS, we can create functions, functions are building blocks that hold responsibility. The responsibility of performing operations, retrieving information and many more. Now, say you are working on a system like a rule engine and you need to evaluate whether condition matches or not and then you need to call some function. To do so, you can use either call, apply or bind.
Use .bind() when you want that function to later be called with a certain context, very useful in events. Whereas, .call() or .apply() when you want to invoke the function immediately, and modify the context. Call() invokes the function and allows you to pass in arguments one by one whereas Apply()invokes the function and allows you to pass in arguments as an array. Here passing parameters in form of array is key and this is a reason I was exploring .apply(). As I was talking about learning with the use case below use case I picked.

Salesforce ActionFunctions

In Salesforce, action functions are used to call controller methods in an async way. The usual flow would be
Create Action-function, Create JS function(that retrieve values,validations), Call JS function that will call Action function.
The main bottleneck(for me), in calling action function from JS functions is passing parameters and validations. Validations can be easily taken care of by JS library but for passing parameter its not the case. Also if the VF page is heavily driven by action function, then you ended up writing so many JS functions. This leads to code readability and maintainability issue.

How can we use Apply() to solve the above problem?

As I mentioned earlier, passing parameters in form of array is key. Why ? because for every action function number of parameters needed is going to be different. So passing it an array is a good option.
Step 1 — Configurations
Now let see, some configuration part, here I have used Html-5 data attributes to hold configuration. If you want to hold any custom attributes, and want to access it pretty easily, you can go for data-* attribute. All you need to do is define data-<custom attribute name> at the element level. And how to access it, using property <element>.dataset.<attributename> . Let see how I used it. I created input buttons and at input buttons, I have created a custom attribute “data-actionfunction” where I am storing a name of action function to be called. While calling action function, we also need to pass parameters, so I have created one more attribute “data-parameter”. To uniquely identify, buttons having action function configured I have attribute “data-action”. Below is the snippet for same.
<input id=”btnAction1" type=”button” data-action=”register” data-actionfunction=”act1" data-parameter=”#txt1" value=”Action1"/>
Step 2 — Event Registration.
As you can see in the above example, I have not added any on-click event. So I will be doing that in this step. Now using attribute “data-action”, we will retrieve all buttons where action function is configured.
// retrieve all buttons
let domelements=_document.querySelectorAll(“input[data-action=’register’]”);
domElements.forEach(function(domElement,index){
    
    //get action function name using dataset. 
    let actionfunction=domElement.dataset.actionfunction;
    if(!!actionfunction){
       // register event.
       domElement.addEventListener(“click”,onclick,false);
    }
});
Step3 — Calling ActionFunction
Step 1 and 2 we are done with the initial setup of configuration and event registration. In this step, we will be doing, retrieve elements value and calling action function with parameters. To do, again dataset attribute will be used. Now, whenever the button is clicked, we will get that button instance using the keyword “this” and we will use it for attribute retrieval.
const scope=this;
let actFunction=scope.dataset.actionfunction;
let parameters=scope.dataset.parameter;
Now using parameter attribute we can do a query on an element and retrieve its value. Below is snippet for same.
function onclick(){
   const scope=this;
   //get action fucntion name
   let actFunction=scope.dataset.actionfunction;
   
   //get elements name, that values need to pass.
   let parameters=scope.dataset.parameter;
   let selectors=parameters.split(“,”);
   let values=[]; // values to be send, hold in this array.
   selectors.forEach(function(dom,index){
        var domEle=document.querySelector(dom);
        values.push(domEle.value);
   });
}
Now the key to call action function is a window variable. Its a global variable, representing the window in which the script is running, is exposed to JavaScript code. So to call action function below code is used.
window[actFunction].apply(null,values);
Complete Function Snippet-
function onclick(){
const scope=this;
//get action fucntion namelet actFunction=scope.dataset.actionfunction; 
//get elements name, that values need to pass.
let parameters=scope.dataset.parameter;
let selectors=parameters.split(“,”);
let values=[]; // values to be send, hold in this array
selectors.forEach(function(dom,index){
   var domEle=document.querySelector(dom);
   values.push(domEle.value);
});
  //as we don’t need to pass any context so first param is null.
  window[actFunction].apply(null,values);
}

Complete snippet

(function(_window,_document){
    let configuration={
       selector:"input[data-action='register']"
     }
     this.ActionWrapper=function(){
        console.log("Action Wrapper Initialized");
     }
     function onclick(){
       const scope=this;
       let actFunction=scope.dataset.actionfunction;
       let parameters=scope.dataset.parameter;         
       let selectors=parameters.split(",");
       let values=[];
       selectors.forEach(function(dom,index){
          var domEle=document.querySelector(dom);
          values.push(domEle.value);
       });                
       window[actFunction].apply(null,values);
     }
     
     this.ActionWrapper.prototype.config=configuration;
      
     this.ActionWrapper.prototype.Initialize=()=>{
       let eleSelector=configuration.selector;
       let eleCount=_document.querySelectorAll(eleSelector);
         SubscribeEvents(eleCount);
       }
     let SubscribeEvents=(domElements)=>{
         domElements.forEach(function(domElement,index){
            let actionfunction=domElement.dataset.actionfunction;
            if(!!actionfunction){
               domElement.addEventListener("click",onclick,false);
             }
          });
      }            
     _window.onload=function(){
           let wrapper=new ActionWrapper();
           wrapper.Initialize();
     }                
})(window,document);
//VF code 
<input id="btnAction1" type="button" data-action="register" data-actionfunction="act1" data-parameter="#txt1" value="Action1"/>
<!-- Action Function Starts-->
<apex:actionFunction name="act1" action="{!ActionCall}" reRender="dummy">
     <apex:param name="param1" assignTo="{!parameter1}" value=""/>
</apex:actionFunction>
I am working on a complete wrapper, where validation, screen loader will be taken care of from wrapper only.

If you have any comments or suggestion, please do let know. 


June 16, 2018

Lightning Console Apps - 'Lightning Component Tab' Labels Display as “Loading…”

June 16, 2018 Posted by tjcool , , No comments

Lightning Console Apps


Lightning console apps help to view multiple records and their related records on the same screen, and quickly work through records from a list using the split view. This Saves lots of time. Creating custom tab in the console is also possible. But there is weird behavior with custom tabs.

If you are working on Lightning console and using the Lightning component as a custom tab in Service Console, the content loads fine but tab label stays on "Loading..." forever.

If you have faced this issue, here's the quick workaround.

1. Put this line in your component.
 //in markup

 <lightning:workspaceAPI aura:id="workspace"/>

2. Add a render event handler to your component's markup.
<aura:handler action="{!c.onRender}" name="render" value="{!this}"></aura:handler>

3. Add below code in action ("onRender") or you can also put the code in init handler
        
        var workspaceAPI = component.find("workspace");
        workspaceAPI.getFocusedTabInfo().then(function(response) {
         var focusedTabId = response.tabId;
         workspaceAPI.setTabLabel({
          tabId: focusedTabId,
          label: "Edit Contact" //set label you want to set
         });
         workspaceAPI.setTabIcon({
          tabId: focusedTabId,
          icon: "utility:add_contact", //set iconyou want to set
          iconAlt: "Edit Contact" //set label tooltip you want to set
         });
        })


May 18, 2018

Salesforce - Feature Developer asking from Years, Switch Statement

May 18, 2018 Posted by tjcool , , , No comments

Switch Statement - Feature Developer asking for Years


Salesforce Dev community has been asking for switch statement for many years( 4+ years) and finally, Salesforce has introduced "switch" in Summer 18. I don't know why Salesforce has taken so much time to introduce a common statement in programming.

Switch

We all know, Switch statement allow us to change the control flow of program execution via a multiway branch. In a Recent release (Summer-18) Salesforce has finally introduced "switch" statement. Flavor of "switch" that Salesforce has introduced is bit different. What we have seen (at least me) "switch - case", whereas Salesforce has come with "switch-when".
When I used it, I got a feeling of writing "if-else if" 😁 .

This change applies to Lightning Experience and Salesforce Classic in Enterprise, Performance, Unlimited, and Developer editions.

Check out the below syntax of a switch-

switch on expression {
    when value1 {  // when block 1
        // code block 1
    } 
    when value2,value3 {  // when block 2
        // code block 2
    }
    when value4 {  // when block 3
        // code block 3
    }
    when else {    // default block, optional
        // code block 4
    }
}

Here when a value can be a single value, multiple values, or sObject types.The switch statement evaluates the expression, executes the code block but if no value matches, then when else code block is executed.

Switch statement expressions support following types.

  • Integer
  • Long
  • sObject
  • String
  • Enum

When values can be of following forms.

  • when literal {} (a when block can have multiple, comma-separated literal clauses)
  • when SObjectType identifier {}
  • when enum_value {}

Some of the Example of Switch

Single Value Example: 

switch on datatype {
   when 'string' {
       string.valueof(variablename);
   }
   when 'decimal' {
       Decimal.valueof(variablename);
   }
   when else {
       System.debug('default');
   }
}

Multiple Values Examples: 

switch on i {
   when 2, 3, 4 {
       System.debug('when block 2 and 3 and 4');
   }
   when 5, 6 {
       System.debug('when block 5 and 6');
   }
   when 7 {
       System.debug('when block 7');
   }
   when else {
       System.debug('default');
   }
}

Working with sObjects : 

switch on sobject {
   when Account a {
       System.debug('account ' + a);
   }
   when Contact c {
       System.debug('contact ' + c);
   }
   when null {
       System.debug('null');
   }
   when else {
       System.debug('default');
   }
}

Working With ENUM-

switch on userType {
   when admin {
       System.debug('admin');
   }
   when guest {
       System.debug('guest');
   }
   when else {
       System.debug('none of the above');
   }
}

References-

Thanks to @Rahul Agrawal for sharing.


Please do comment, like and Subscribe -

May 17, 2018

Salesforce : Use Single Inbound Email Service to Process Various Emails .

May 17, 2018 Posted by tjcool , , No comments

- Use Single Inbound Email Service to Process Various Emails -

You can use Apex to receive and process email and attachments. The email is received by the Apex email service and processed by Apex classes that utilize the InboundEmail object.

For example - You can create an email service that automatically creates contact records based on contact information in messages

In this post, we will be covering, use case where Salesforce will be receiving an email from different automated systems say Fax system or from Particular email alias.

Part I - Apex Code for Dynamically Processing Email -

We will be invoking class dynamically in this part. Below are the steps for same.

a) Create Interface 

global class IEmailProcessor {
    object Process(Messaging.inboundEmail email);
}

b) Implement Class IEmailProcessor 

global class FaxProcessor implements IEmailProcessor  {
  public object Process(Messaging.inboundEmail email){
 //All email processing logic will come over here like record creation
  }
}

Part II- Creating Apex Class for Email Service - 

1. Create Apex class and implement interface Messaging.InboundEmailHandler
2. Using "handleInboundEmail" method in that class, you can access an InboundEmail object to retrieve the contents, headers, and attachments of inbound email messages. "handleInboundEmail" has two parameters
   a) Inbound email: Represents an inbound email object and can say contains complete details about an email like attachments, message, sender details.
   b) InboundEnvelope: The InboundEnvelope object stores the envelope information associated with the inbound email, and has fields fromAddress and toAddress.

Snippet - 

global class EmailExample implements Messaging.InboundEmailHandler {
 
  global Messaging.InboundEmailResult handleInboundEmail(Messaging.inboundEmail email, Messaging.InboundEnvelope env){
  
    // Create an InboundEmailResult object for returning the result of the  Apex Email Service
    Messaging.InboundEmailResult result = new Messaging.InboundEmailResult();
    try{    
       //Add the email plain text into the local variable 
       string sender=email.fromname;
       EmailProcessor__c apexClass= EmailProcessor__c.getValues(sender);
       if(apexClass.isActive__c){
          //Create type
          Type type = Type.forName(apexClass.Apex_Class__c);

          //using new instance we create ew instance of class.  
          object instance = type.newInstance();
          
          //typecast
          IEmailProcessor interfaceInstance = (IEmailProcessor)instance;
          
          //invoke method
          object result= interfaceInstance.Process(email);
       }else{
         result.success = false;
       }
   }  
   // If an exception occurs when the query accesses 
   catch (QueryException e) {
       System.debug('Query Issue: ' + e);
   }
   
   // Set the result to true. No need to send an email back to the user with an error message 
    result.success = true;
   
   // Return the result for the Apex Email Service
   return result;
  }
}

Part III - Setting Up Email Service in Salesforce - 

Step1 -  Click Your Name > Setup > Develop > Email Services

Step2 & Step3 -


In my case apex, the class value would be: EmailExample 

Part IV - Create Custom Setting for Email and Apex class mapping. 

Below is a snapshot of my custom setting and field.



Populate custom settings with apex class and alias email address. Now when Salesforce will receive an email your class will get invoked and checks if the email is coming from configured service or not and if it so the appropriate class will get invoked.


Hope this Helpfull. Please Comment and Subscribe


May 10, 2018

Introduction - Client-side Template

May 10, 2018 Posted by tjcool , , , , No comments

In the world, where we have so many front-end frameworks around us, for some people this post is bit outdated. But, I thought sharing information is always helpful. 

Flashback……

We all know, when a web page is loaded, the browser creates a Document Object Model of the page. 
The HTML DOM model is constructed as a tree of Objects. With the object model, JavaScript gets all the power it needs to create dynamic HTML. And we all have created dynamic elements using javascript (at least I have done it :) )



Dynamic Element Creation - The approach we follow usually.

When developing modern HTML applications, we often write a lot of HTML fragments programmatically. We concatenate HTML tags and dynamic data and insert the resulting UI markup into the DOM.

Below are the random code example of this approach

 https://jsfiddle.net/tjcool/5qjLpo6t/

Code to Create or Add dynamic Content on the page : 

Javascript : 


Jquery - Code to add user messages in the container. 



And the problem starts…

For simple Dom manipulation, we write similar snippets shown in above previous examples.

Day by day as requirement gets complicated we start facing issues, issues like managing code, scripting performance issues, user experience, cross-browser compatibility. We end up writing code of thousand lines with a lot of dom manipulation.
It makes your application very tightly coupled and harder to maintain.
So, when we should avoid client-side Dom manipulation. So, based on my previous experiences and references from forums following are some of the use cases.
  • Complex projects which involve large amounts of client-side HTML manipulation with JavaScript.
  • When client expects good UX.
  • When you need to support mobile device as well.


Note: Use of jQuery clone, append method heavily as a clone and append methods degrade application performance if involved in large DOM manipulation. 

What is Template - First Impression.

“A document that contains parameters, identified by some special syntax, that are replaced by actual arguments by the template processing system.”

Quick Example -


When & Why would you use It 

In today’s world of dynamic applications, the client frequently wants moreover like plug and play user interface (UI) or can say dynamic UI and of course styling. This can be done by fetching an HTML fragment from the server that can be readily inserted into the document. Also, as a  developer, you want to have full control over your UI as well.

So let’s take a look at templating(client-side templating)

There are a number of HTML template solutions out there: 
  • Mustache.js
  • Handlebar.js 
  • Underscore.js 
Mustache.js is a popular choice because of its powerful syntax and fast rendering. In fact, Handlebar is a more advanced version of Mustache. There are also other front-end frameworks which use Mustache for UI rendering.



Please do comment, like and Subscribe