August 31, 2020

Send Email to Members in Salesforce Queue


An Email is sent to all Queue members individually when new records are placed in the Queue if:

1. The Queue Email field is left Blank regardless if the 'Send Email to Members' checkbox is selected or notOR

2. When there is a Queue Email specified AND the 'Send Email to Members' checkbox is selected.

The Send Email to queue members alert will only work if you are using Case Assignment Rules and Active Assignment checkbox to move Case to a Queue. If you are moving the case Manually to a Queue or using a Workflow, it does not trigger the Email alert. The Email is also triggered when a Lead is created from a Web-to-Lead form.


Referece Link - https://help.salesforce.com/articleView?id=000323036&type=1&mode=1

August 29, 2020

Salesforce Winter '21 Release Highlights/Overview

Track Chat Conversations with a New Message Icon
Provide a modern experience for your Embedded Chat users with a sleek new message notification and arrow. The icon, showing the number of unread messages, appears in the chat window above those messages. The user can scroll down to read and know when an agent is typing.


 

Use the Safe Navigation Operator to Avoid Null Pointer Exceptions
Use the safe navigation operator (?.) to replace explicit, sequential checks for null references. This new operator short-circuits expressions that attempt to operate on a null value and returns null instead of throwing a NullPointerException.

This example first evaluates a, and returns null if a is null. Otherwise, the return value is a.b.
a?.b // Evaluates to: a == null? Null : a.b

Send Custom Notifications from Apex
Use the Messaging.CustomNotification class to create, configure, and send custom notifications directly from Apex code, such as a trigger.

Improve Apex Testing with New SObject Error Methods
Track errors with the new SObject.hasErrors() and SObject.getErrors() methods without performing a DML operation to check the result for errors. Dynamically add errors to specific fields with new SObject.addError() overload methods. Use the hasErrors() method to know if an SObject instance contains errors. Use the getErrors() method to retrieve the list of errors for a specific SObject instance.

How to sign up for Salesforce Winter '21 Pre-Release org?

1. Go to https://www.salesforce.com/form/signup/prerelease-winter21/.

 2. Enter all the information. Click Start Trial to sign up.


August 28, 2020

How to revert or rollback Salesforce Mobile and Lightning Experience Actions?

1. Open the Page Layout.

2. Hover or mouse over "Salesforce Mobile and Lightning Experience Actions" and click the undo icon.


Reference Link

https://help.salesforce.com/articleView?id=adding_actions_using_ple.htm&type=5

August 27, 2020

Fetch records matching today's date and update them daily using Apex in Salesforce?

AccountEffectiveBatch - Batch class to fetch Account records matching effectiveDate.

AccountEffectiveBatchSchedule - Scheduler to call schedule it daily. This will call the AccountEffectiveBatch class and pass today's date.

AccountEffectiveBatchSchedule is scheduled to run daily at 10 PM until 27th August 2030.

1. Create a Custom field with Data datatype in Account object.

 

2. Create the Batch Class.

global class AccountEffectiveBatch implements Database.Batchable<sObject> {
   
    global Date effectiveDate;
   
    global AccountEffectiveBatch( Date effectiveDate ) {
       
        this.effectiveDate = effectiveDate;
       
    }
 
    global Database.QueryLocator start( Database.BatchableContext BC ) {
        
        /* Fetching all Accounts where Effective_Date__c date is matched
        format() Converts the date to the local time zone and returns the converted date as a formatted string using the locale of the context user.
        If the time zone cannot be determined, GMT is used.*/
        String query = 'SELECT Id,Name FROM Account WHERE Effective_Date__c = ' + String.valueOf( effectiveDate );
        return Database.getQueryLocator( query );
 
    }
  
    global void execute( Database.BatchableContext BC, List< Account > scope ) {
       
         /* Updating Accounts descrition */
         for ( Account a : scope ) {
            
             a.Description = 'Updated on ' + DateTime.now().format();     
            
         }
         update scope;
       
    }  
   
    global void finish( Database.BatchableContext BC ) {
    }
 
}


3. Create the Scheduler Class.

/* Schedule class to schedule call the Batch class*/
global class AccountEffectiveBatchSchedule implements Schedulable {
   
    global void execute( SchedulableContext SC ) {
       
        /*Passing today date to the Batch Class
        Date.today() Returns the current date in the current user's time zone.*/
        AccountEffectiveBatch obj = new AccountEffectiveBatch( Date.today() );
        Database.executeBatch( obj );
       
    }
   
}


4. Schedule the Scheduler Class.

 



Test Class:

@isTest
private class AccountEffectiveBatchTest {
   
    static testMethod void acctEffectTest() {
       
        Date dtToday = Date.today();
        Account acc =  new Account( Name = 'Test', Effective_Date__c = dtToday );
        insert acc;
        Test.startTest();
        AccountEffectiveBatchSchedule obj = new AccountEffectiveBatchSchedule(); 
        obj.execute( null );
        Test.stopTest();
        acc = [ SELECT Id, Description FROM Account WHERE Id =: acc.Id ];
        system.assert( acc.Description.contains( String.valueOf( dtToday ) ) );
       
    }

}

Output:


How to Hyperlink a Parent Record in lightning:datatable?

Sample Code:

Component:


<aura:component implements="force:appHostable"
                   controller="ContactListController">
               
    <aura:attribute type="Contact[]" name="conList"/>
    <aura:attribute name="mycolumns" type="List"/>
   
    <aura:handler name="init" value="{!this}" action="{!c.fetchConts}"/>
   
    <lightning:datatable data="{! v.conList }"
                         columns="{! v.mycolumns }"
                         keyField="Id"
                         hideCheckboxColumn="true"/>
   
</aura:component>

Component Controller:

({
   
    fetchConts : function( component, event, helper ) {
       
        component.set('v.mycolumns', [
            { label: 'First Name', fieldName: 'FirstName', type: 'text' },
            { label: 'Last Name', fieldName: 'LastName', type: 'Text' },
            { label: 'Account Name', fieldName: 'linkName', type: 'url',
            typeAttributes: { label: { fieldName: 'AccountName' }, target: '_blank' } }
        ]);
        var action = component.get( "c.fetchContacts" );
        /*action.setParams({
        });*/
        action.setCallback(this, function( response ) {
           
            var state = response.getState();
            if ( state === "SUCCESS" ) {
               
                console.log( 'Success' );
                var records = response.getReturnValue();
                records.forEach( function( record ) {
                    record.AccountName = record.Account.Name;
                    record.linkName = '/' + record.Account.Id;
                });
                component.set( "v.conList", records );
               
            }
           
        });
        $A.enqueueAction( action );
       
    }

})

Apex Class:

public class ContactListController {
   
    @AuraEnabled
    public static List < Contact > fetchContacts() {
       
        return [ SELECT Id, FirstName, LastName, Account.Id, Account.Name FROM Contact LIMIT 10 ];
       
    }

}

Output:



August 25, 2020

ApexClass.SubClass does not have a no-arg constructor Exception in Salesforce

To avoid this exception, pass String from the Aura JavaScript to the Apex class and use JSON.deSerialize() to convert the String to wrapper class list in the Apex Class.

Sample Code with Error:

Component:


<aura:component implements="force:appHostable"
                   controller="AccountListController">
                
    <lightning:button label="Click" onclick="{!c.callCheckValues}"></lightning:button>
    
</aura:component>

JavaScript:

({
    
    callCheckValues : function( component, event, helper ) {
        
        var listWrappers = [];
        listWrappers.push( { "strName" : "Test", "strAddress" : "Testing 123" } );
        console.log( 'Wrapper List is ' + JSON.stringify( listWrappers ) );
        var action = component.get( "c.checkValues" );
        action.setParams({
            "listWrappers" : listWrappers
        });
        action.setCallback( this, function( response ) {
            console.log( 'Response is ' + JSON.stringify( response.getReturnValue() ) );
        });
        $A.enqueueAction( action );
        
    }

})

Apex Class:

public class AccountListController {
    
    @AuraEnabled
    public static List < Wrapper > checkValues( List < Wrapper > listWrappers ) {
        
        try {
            for ( Wrapper objWrap : listWrappers ) {
                
                system.debug( 'Name is ' + objWrap.strName );
                system.debug( 'Address is ' + objWrap.strAddress );
                
            }
            system.debug( 'Wrapper is ' + listWrappers );
            return listWrappers;
        } catch( Exception e ) {
            
            system.debug( 'Exception is ' + e.getMessage() );
            return null;
            
        }
        
    }
    
    public class Wrapper {
        
        @AuraEnabled
        public String strName { get; set; }
        @AuraEnabled
        public String strAddress { get; set; }
        
        public Wrapper() {
            
            strName = '';
            strAddress = '';
            
        }
        
        public Wrapper( String strname, String strAddress ) {
            
            strName = this.strName;
            strAddress = this.strAddress;
            
        }
        
    }
    
}

Sample Code with Fix:

JavaScript:

({
    
    callCheckValues : function( component, event, helper ) {
        
        var listWrappers = [];
        listWrappers.push( { "strName" : "Test", "strAddress" : "Testing 123" } );
        console.log( 'Wrapper List is ' + JSON.stringify( listWrappers ) );
        var action = component.get( "c.checkValues" );
        action.setParams({
            "strWrapper" : JSON.stringify( listWrappers )
        });
        action.setCallback( this, function( response ) {
            console.log( 'Response is ' + JSON.stringify( response.getReturnValue() ) );
        });
        $A.enqueueAction( action );
        
    }

})

Apex Class:

public class AccountListController {
    
    @AuraEnabled
    public static List < Wrapper > checkValues( String strWrapper ) {
        
        List < Wrapper > listWrappers = ( List < Wrapper > )JSON.deSerialize( strWrapper, List < Wrapper >.class );
        try {
            for ( Wrapper objWrap : listWrappers ) {
                
                system.debug( 'Name is ' + objWrap.strName );
                system.debug( 'Address is ' + objWrap.strAddress );
                
            }
            system.debug( 'Wrapper is ' + listWrappers );
            return listWrappers;
        } catch( Exception e ) {
            
            system.debug( 'Exception is ' + e.getMessage() );
            return null;
            
        }
        
    }
    
    public class Wrapper {
        
        @AuraEnabled
        public String strName { get; set; }
        @AuraEnabled
        public String strAddress { get; set; }
        
        public Wrapper() {
            
            strName = '';
            strAddress = '';
            
        }
        
        public Wrapper( String strname, String strAddress ) {
            
            strName = this.strName;
            strAddress = this.strAddress;
            
        }
        
    }
    
}

Dynamic Field required and error message in Salesforce LWC

Sample Code:

HTML:

<template>

    <div class="slds-theme--default slds-p-around_large">

        <lightning-input type="toggle" label="Basic option" name="toggle" onchange={onHandleValueChange}></lightning-input><br/><br/>
        <lightning-input type="text" label="Enter some text" name="text" required={requiredBool}  class="inputText"></lightning-input>

    </div>
  
</template>

JavaScript:

import { LightningElement } from "lwc";

export default class Sample extends LightningElement {

    requiredBool = false;
    showBool = true;

    onHandleValueChange( event ) {

        let selectedVal = event.detail.checked;
        console.log( "Event is " + JSON.stringify( event.detail ) );
        console.log( "Selected Val is " + selectedVal );
        if ( selectedVal === true ) {

            this.requiredBool = true;
            let inputText = this.template.querySelector( ".inputText" );
            inputText.setCustomValidity( "This field is required/mandatory" );
            inputText.reportValidity();

        }
        else {

            let inputText = this.template.querySelector( ".inputText" );
            let tempBool = false;
            if ( !inputText.value ) {
                /* Setting value to Temp to avoid Value Missing error message */
                inputText.value = "Temp";
                tempBool = true;
            }
            inputText.setCustomValidity( "" );
            inputText.reportValidity();
            this.requiredBool = false;
            if ( tempBool )
                inputText.value = undefined;

        }

    }

}

Output:

 


August 24, 2020

JavaScript Interview Questions with Answers Part 1

1. Object value settings or Initialisation in JavaScript

1. Dot Operator
var objPerson = new Object();
objPerson.FirstName = 'John';
objPerson.LastName = 'Brad';
objPerson.Age = 1969;

2. Object Initialiser - comma-delimited
var objPerson = {
    FirstName: 'John',
    LastName: 'Brad',
    Age: 1969
};

3. Constructor Function
function Person(FirstName, LastName, Age) {
  this.FirstName = FirstName;
  this.LastName = LastName;
  this.Age = Age;
}

4. Object.create()
// Animal properties and method encapsulation
var Animal = {
  type: 'Invertebrates', // Default value of properties
  displayType: function() {  // Method which will display type of Animal
    console.log(this.type);
  }
};

// Create new animal type called animal1 
var animal1 = Object.create(Animal);
animal1.displayType(); // Output:Invertebrates

// Create new animal type called Fishes
var fish = Object.create(Animal);
fish.type = 'Fishes';
fish.displayType(); // Output:Fishes

5. Square Bracket Notation
objPerson['FirstName'] = 'John';
objPerson['LastName'] = 'Brad';
objPerson['Age'] = 1969;

An object property name can be any valid JavaScript string, or anything that can be converted to a string, including the empty string. However, any property name that is not a valid JavaScript identifier (for example, a property name that has a space or a hyphen, or that starts with a number) can only be accessed using the square bracket notation. This notation is also very useful when property names are to be dynamically determined (when the property name is not determined until runtime).

2. Functions in JavaScript
Primitive parameters (such as a number) are passed to functions by value; the value is passed to the function, but if the function changes the value of the parameter, this change is not reflected globally or in the calling function.

If you pass an object (i.e. a non-primitive value, such as Array or a user-defined object) as a parameter and the function changes the object's properties, that change is visible outside the function, as shown in the following example:

function myFunc(theObject) {
  theObject.Firstname = 'John';
}

var mycar = {Firstname: 'Smith', Lastname: 'Bob', Age: 55};
var x, y;

x = mycar.Firstname; // x gets the value "John"

myFunc(mycar);
y = mycar.Firstname; // y gets the value "John"
                // (the Firstname property was changed by the function)
                
function hoisting only works with function declarations—not with function expressions:
Below code will work.
console.log( cube( 5 ) );
/* ... */
function square(n) { return n * n *n }

Below code will fail:
console.log(square)    // square is hoisted with an initial value undefined.
console.log(square(5)) // Uncaught TypeError: square is not a function
const square = function(n) {
  return n * n;
}

Recursive Function:
If a function calls itself, then it is Recursive Function.
In fact, recursion itself uses a stack: the function stack. The stack-like behaviour can be seen in the following example:

function foo(i) {
  if (i < 0)
    return;
  console.log('begin: ' + i);
  foo(i - 1);
  console.log('end: ' + i);
}
foo(3);

// Output:

// begin: 3
// begin: 2
// begin: 1
// begin: 0
// end: 0
// end: 1
// end: 2
// end: 3

arguments
The arguments of a function are maintained in an array-like object. Within a function, you can address the arguments passed to it as follows:

arguments[i]

The arguments variable is "array-like", but not an array. It is array-like in that it has a numbered index and a length property. However, it does not possess all of the array-manipulation methods.

3. The finally block 
The finally block contains statements to be executed after the try and catch blocks execute. Additionally, the finally block executes before the code that follows the try…catch…finally statement. It is also important to note that the finally block will execute whether or not an exception is thrown. If an exception is thrown, however, the statements in the finally block execute even if no catch block handles the exception that was thrown.
If the finally block returns a value, this value becomes the return value of the entire try…catch…finally production, regardless of any return statements in the try and catch blocks.

Overwriting of return values by the finally block also applies to exceptions thrown or re-thrown inside of the catch block:

function f() {
  try {
    throw 'bogus';
  } catch(e) {
    console.log('caught inner "bogus"');
    throw e; // this throw statement is suspended until 
             // finally block has completed
  } finally {
    return false; // overwrites the previous "throw"
  }
  // "return false" is executed now
}

try {
  console.log(f());
} catch(e) {
  // this is never reached! 
  // while f() executes, the `finally` block returns false, 
  // which overwrites the `throw` inside the above `catch`
  console.log('caught outer "bogus"');
}

Output:
// caught inner "bogus"
// false

4. Difference between a for...of loop and a for...in loop. 
While for...in iterates over property names, for...of iterates over property values:

Example:
const arr = [3, 5, 7];
arr.foo = 'hello';

for (let i in arr) {
   console.log(i); // logs "0", "1", "2", "foo"
}

for (let i of arr) {
   console.log(i); // logs 3, 5, 7
}

5. Composition
Promise.resolve() and Promise.reject() are shortcuts to manually create an already resolved or rejected promise respectively.
Promise.all() and Promise.race() are two composition tools for running asynchronous operations in parallel.

6. Weakmap
The WeakMap object is a collection of key/value pairs in which the keys are weakly referenced. The keys must be objects and the values can be arbitrary values.

7. Weakset
WeakSet objects are collections of objects. Just as with Sets, each object in a WeakSet may occur only once; all objects in a WeakSet's collection are unique.

The main differences to the Set object are:

WeakSets are collections of objects only.  They cannot contain arbitrary values of any type, as Sets can.
The WeakSet is weak, meaning references to objects in a WeakSet are held weakly. If no other references to an object stored in the WeakSet exist, those objects can be garbage collected.

8. HTML, CSS and JavaScript

HTML is the markup language that we use to structure and give meaning to our web content, for example defining paragraphs, headings, and data tables, or embedding images and videos in the page.

CSS is a language of style rules that we use to apply styling to our HTML content, for example setting background colours and fonts, and laying out our content in multiple columns.

JavaScript is a scripting language that enables you to create dynamically updating content, control multimedia, animate images, and pretty much everything else. 
JavaScript is a scripting or programming language that allows you to implement complex features on web pages — every time a web page does more than just sit there and display static information for you to look at — displaying timely content updates, interactive maps, animated 2D/3D graphics, scrolling video jukeboxes, etc. — you can bet that JavaScript is probably involved. 

9. What is the advantage of having separate JavaScript Files? 
The benefit of a separate file is that the browser will download it and store it in its cache. Other pages that reference the same script will take it from the cache instead of downloading it, so the file is actually downloaded only once. That reduces traffic and makes pages faster.

10. Same Origin Policy
Different tabs/windows generally do not know about each other. Sometimes they do, for example when one window uses JavaScript to open the other one. But even in this case, JavaScript from one page may not access the other if they come from different sites (from a different domain, protocol or port).

This is called the “Same Origin Policy”. To work around that, both pages must agree for data exchange and contain a special JavaScript code that handles it. We’ll cover that in the tutorial.

This limitation is, again, for the user’s safety. A page from http://anysite.com which a user has opened must not be able to access another browser tab with the URL http://gmail.com and steal information from there.

11. Automatic semicolon insertion
A semicolon may be omitted in most cases when a line break exists.

This would also work:
alert('Hello')
alert('World')

Here, JavaScript interprets the line break as an “implicit” semicolon. This is called an automatic semicolon insertion.
 
There are cases when a newline does not mean a semicolon. For example:

alert(3 +
1
+ 2);
 
 JavaScript does not assume a semicolon before square brackets [...].

12. use strict
The "use strict" directive was new in ECMAScript version 5.
It is not a statement, but a literal expression, ignored by earlier versions of JavaScript.
The purpose of "use strict" is to indicate that the code should be executed in "strict mode".
With strict mode, you can not, for example, use undeclared variables.

13. Variable naming
There are two limitations on variable names in JavaScript:

    The name must contain only letters, digits, or the symbols $ and _.
    The first character must not be a digit.

Examples of valid names:

let userName;
let test123;

14. Object.assign()

The Object.assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the target object.

Syntax
Object.assign(target, ...sources)

Sample Code:
const target = { a : 1, b : 2 };
const source = { b : 3, c : 4 };
const returnedTarget = Object.assign( target, source );
console.log( 'After Assgin - Target ' + JSON.stringify( target ) );
console.log( 'After Assign - Source ' + JSON.stringify( returnedTarget ) );

Output:
"After Assgin - Target {"a":1,"b":3,"c":4}"
"After Assign - Source {"a":1,"b":3,"c":4}"

Cloning:
const obj = { a : 1 };
const copy = Object.assign( {}, obj );
console.log( 'Obj is ' + JSON.stringify( obj ) );
console.log( 'Copy is ' + JSON.stringify( copy ) );

Output:
"Obj is {"a":1}"
"Copy is {"a":1}"

15. The “undefined” value
The special value undefined also stands apart. It makes a type of its own, just like null.
The meaning of undefined is “value is not assigned”.
If a variable is declared, but not assigned, then its value is undefined:
let age;
alert(age); // shows "undefined"

August 20, 2020

Salesforce Exception You can't perform this action. Be sure the action is valid for the current state of the article, and that you have permission to perform it.

1. Check the profile permissions for the user.

2. Issue may be due to the Picklist field value or if the record is locked due to Approval Process.
https://help.salesforce.com/articleView?id=000314555&type=1&mode=1

3. Check this known issue https://trailblazer.salesforce.com/issues_view?id=a1p3A000001SHxuQAG

4. If you are getting this error when clicking "Edit as Draft" button, query the field values and make sure the values are under the character limit for all the fields on the page layout.

August 18, 2020

How to set DateTime with current year using Apex in Salesforce?

 Sample Code:

/*

Constructs a DateTime from the specified date and time in the local time zone.

Date.today() returns the current date in the current user's time zone.

*/

Date dtToday = Date.today();

/* Setting October 1st of current Year */

Date myDate = Date.newInstance( dtToday.year(), 10, 1 );

Time myTime = Time.newInstance( 3, 3, 3, 0 );

DateTime objDT = DateTime.newInstance( myDate, myTime );

/* Using format() since teh objDT return value will be in GMT */

system.debug( 'Date Time is ' + objDT.format() );

Output:


DateTime new instance using Apex in Salesforce

 Sample Code:

/*Constructs a DateTime from the specified date and time in the local time zone.*/
Date myDate = Date.newInstance( 2020, 10, 30 );
Time myTime = Time.newInstance( 3, 3, 3, 0 );
DateTime objDT = DateTime.newInstance( myDate, myTime );
/* Using format() since teh objDT return value will be in GMT */
system.debug( 'Date Time is ' + objDT.format() );

Output:


August 15, 2020

How to redirect users to a specific Lightning App Salesforce?

To direct your users to a specific location after authenticating, specify a URL with the startURL request parameter.

https://login.salesforce.com?app=06m5w000001ZzcbA
This opens an App based on the Id used in the app based on the App Id used.

https://login.salesforce.com?app=06m5w000001ZzcbA&startURL=/lightning/r/Case/5005w00001boFlIAAU/view
This opens a Case record in the app based on the App Id used.

https://login.salesforce.com?app=06m5w000001ZzcbA&startURL=/lightning/o/Account/list
This opens pinned Account List View in the app based on the App Id used.

https://login.salesforce.com?app=06m5w000001ZzcbA&startURL=/lightning/o/Account/list?filterName=00B5w00000CkcluEAB
This opens Account List View based on the List View Id in the app based on the App Id used.

August 12, 2020

How to get default field values set in URL in Lightning Aura Components in Salesforce?

 Sample Code:

Component:

 <aura:component implements="flexipage:availableForRecordHome,force:hasRecordId,lightning:actionOverride,lightning:isUrlAddressable" access="global" >
   
    <aura:attribute name="recordId" type="String"/>
   
    <lightning:notificationsLibrary aura:id="notifLib"/>
   
    <div class="slds-box slds-theme--default">
       
        <lightning:recordEditForm objectApiName="Lead" onload="{!c.handleCreateLoad}">
            <lightning:messages />
            <lightning:inputField fieldName="FirstName" aura:id="FirstName"/>
            <lightning:inputField fieldName="LastName" aura:id="LastName"/>
            <lightning:inputField fieldName="Email" aura:id="Email"/>
            <lightning:inputField fieldName="Company" aura:id="Company"/>
            <lightning:inputField fieldName="LeadSource" aura:id="LeadSource"/>
            <lightning:button class="slds-m-top_small" variant="brand" type="submit" name="Create" label="Create" />
        </lightning:recordEditForm>
       
    </div>
   
</aura:component>

JavaScript:

({
   
    handleCreateLoad : function(cmp, event, helper) {
       
        var myPageRef = cmp.get("v.pageReference");
        console.log( 'Pagereference is ' + JSON.stringify( myPageRef ) );
        console.log( 'Default Values are ' + JSON.stringify( myPageRef.state.defaultFieldValues ) );
       
        if ( myPageRef.state.defaultFieldValues ) {
           
            myPageRef.state.defaultFieldValues.split( "," ).forEach( function( record ) {
               
                var recordSplit = record.split( "=" );
                cmp.find( recordSplit[ 0 ] ).set( "v.value", recordSplit[ 1 ] );
               
            });                        
           
        }
       
    }
   
})

Button Override:

 Output:

Use this path to test it - /lightning/o/Lead/new?defaultFieldValues=FirstName=Test1,LastName=Test2,Email=test@dd.com,Company=Testing

 


August 7, 2020

How to use Name instead of Id in lightning:dataTable URL

tooltip can be used to show Name instead of Id in URL type.

Sample Code:

Component:

 <aura:component implements="force:appHostable"
                   controller="AccountListController">
               
    <aura:attribute type="Account[]" name="acctList"/>
    <aura:attribute name="mycolumns" type="List"/>
   
    <aura:handler name="init" value="{!this}" action="{!c.fetchAccounts}"/>
   
    <lightning:datatable data="{! v.acctList }"
                         columns="{! v.mycolumns }"
                         keyField="Id"
                         hideCheckboxColumn="true"/>
   
</aura:component>

Component Controller:

 ({
   
    fetchAccounts : function(component, event, helper) {
        component.set('v.mycolumns', [
            {label: 'Account Name', fieldName: 'linkName', type: 'url',
             typeAttributes: { label: { fieldName: 'Name' }, target: '_blank', tooltip: { fieldName: 'Name' } } },
            {label: 'Industry', fieldName: 'Industry', type: 'text'},
            {label: 'Type', fieldName: 'Type', type: 'Text'}
        ]);
        var action = component.get("c.fetchAccts");
        action.setParams({
        });
        action.setCallback(this, function(response){
            var state = response.getState();
            if (state === "SUCCESS") {
                var records =response.getReturnValue();
                records.forEach(function(record){
                    record.linkName = '/'+record.Id;
                });
                component.set("v.acctList", records);
            }
        });
        $A.enqueueAction(action);
    }


})

Apex Class:

 public class AccountListController {
    
    @AuraEnabled
    public static List < Account > fetchAccts() {
        
        return [ SELECT Id, Name, Industry, Type FROM Account LIMIT 10 ];
        
    }
    
}

Output:

August 6, 2020

Events with multiple values communication in Salesforce LWC

Lightning web components dispatch standard DOM events. Components can also create and dispatch custom events. Use events to communicate up the component containment hierarchy. For example, a child component, c-todo-item, dispatches an event to tell its parent, c-todo-app, that a user selected it.

Create and Dispatch Events
Create and dispatch events in a component’s JavaScript class. To create an event, use the CustomEvent() constructor. To dispatch an event, call the EventTarget.dispatchEvent() method.

The CustomEvent() constructor has one required parameter, which is a string indicating the event type. As a component author, you name the event type when you create the event. You can use any string as your event type. However, we recommend that you conform with the DOM event standard.

No uppercase letters
No spaces
Use underscores to separate words

Don’t prefix your event name with the string on, because inline event handler names must start with the string on. If your event is called onmessage, the markup would be <c-my-component ononmessage={handleMessage}>. Notice the doubled word onon, which is confusing.

Sample Code:

Sample HTML:

<template>

    <div class="slds-box slds-theme--default"> 
    
        Enter your Basic Information below
        <c-contact-form onentered={handleFromContact}></c-contact-form>

    </div>

</template>

Sample JavaScript:

import { LightningElement } from 'lwc';

export default class Sample extends LightningElement {
    
    handleFromContact( event ) {

        console.log ( 'Values are ' + JSON.stringify( event.detail ) );
        console.log ( 'First Name is ' + event.detail.fname );
        console.log ( 'First Name is ' + event.detail.lname );
        console.log ( 'First Name is ' + event.detail.age );

    }

}

Contact Form HTML:

<template>

    <lightning-card  title="Basic Information">

        <lightning-button label="Update" onclick={updateParent} slot="actions"></lightning-button>

        <p class="slds-p-horizontal_small">

            <lightning-input type="text" label="First Name" name="fname" onchange={handleFormInputChange}></lightning-input>
            <lightning-input type="text" label="Last Name" name="lname" onchange={handleFormInputChange}></lightning-input>
            <lightning-input type="number" label="Age" name="age" onchange={handleFormInputChange}></lightning-input>
        
        </p>

        <p slot="footer">Complete the Basic Information</p>

    </lightning-card>
    
</template>

Contact Form JavaScript:

import { LightningElement, track } from 'lwc';

export default class ContactForm extends LightningElement {

    @track 
    firstName;
    @track 
    lastName
    @track
    age;

    handleFormInputChange( event ) {

        switch ( event.target.name ) {

            case "fname":
                this.firstName = event.detail.value;
                break;
            case "lname":            
                this.lastName = event.detail.value;
                break;
            case "age":            
                this.age = event.detail.value;
                break;

        }
        
        
    }

    updateParent() {

        const selectedEvent = new CustomEvent( 'entered', { detail: { fname : this.firstName, lname : this.lastName, age : this.age } } );
        this.dispatchEvent( selectedEvent) ;

    }

}

Output:


August 1, 2020

Live Message Session reuse time (seconds) in Salesforce Classic

Live Message Session reuse time (seconds)

The time between when a LiveMessage session is ended and a new message is received that an LiveMessage session should be reused. The Auto-Response Message, Text Session Start Message and the Text Session End Message aren't sent if a new LiveMessage session is received within the specified time period.

When Session Reuse Time is in use, the reopened message appears in agents omni-channel widget. Messaging Session will reopen.

Check below for more information

https://heywire.my.salesforce.com/sfc/p/#F0000000559Q/a/0G000000TDp7/KUMnkrkbzR9RHM.aU4CFguRVL3z7mGmz4kG8SS1UAJ8

Simple lightning-button-menu example in Salesforce LWC

Sample code:

HTML:

<template>

    <div class="slds-box slds-theme--default"> 

        <lightning-button-menu alternative-text="Show menu" variant="border-filled" onselect={handleOnselect} label="Actions">
            <lightning-menu-item value="Account" label="Create Account"></lightning-menu-item>
            <lightning-menu-item value="Contact" label="Create Contact"></lightning-menu-item>
            <lightning-menu-item value="Lead" label="Create Lead"></lightning-menu-item>
            <lightning-menu-item value="Opportunity" label="Create Opportunity"></lightning-menu-item>
        </lightning-button-menu>

    </div>

</template>

JavaScript:

import { LightningElement, api, track } from 'lwc';
import { NavigationMixin } from 'lightning/navigation';

export default class Sample extends NavigationMixin(LightningElement) {
    
    handleOnselect(event) {

        var selectedVal = event.detail.value;
        console.log( 'Selected button is ' + selectedVal );

        this[NavigationMixin.Navigate]({
            type: 'standard__objectPage',
            attributes: {
                objectApiName: selectedVal,
                actionName: 'new'
            }
        });

    }

}

Output: