Wednesday, August 28, 2019

Create Object From Spreadsheet using Lightning Object Creator in Salesforce

Lightning Object Creator is a new tool to create an object from the spreadsheet.

Note: Make sure that Lightning Experience should be enabled in your org.

For Demo, I created a sample spreadsheet with columns.

Step 1:
Go to Setup | Object Manager | Select Custom Object from Spreadsheet
                      OR
you can directly access the tool using below link
https://object-creator.salesforce.com/

Step 2
Upload spreadsheets from Microsoft Excel, Google Sheets, or comma-separated value (CSV) files.
Step 3
Salesforce will automatically detect the fields and populate all its record data from Spreadsheet. You can customize the Salesforce field name and field type or leave them as suggested.
Step 4
Define object Properties and click finish

Result

Monday, August 26, 2019

How to get the Custom Notification Type Id Using SOQL in Salesforce

Note: Select Tooling API to query if you are using the Developer console select the tooling API.

SOQL:
SELECT Id, CustomNotifTypeName FROM CustomNotificationType

Result

Friday, August 23, 2019

How to query all Private Reports in Salesforce

SOQL Query
SELECT Id, Name, Owner.Name FROM Report USING SCOPE allPrivate

Result

Wednesday, August 21, 2019

How to add Lightning Web Components as Custom Tabs in Salesforce

Form Winter '20 onwards you can add the Lightning Web Component as Custom Tab in Salesforce.

The <component>.js-meta.xml configuration file defines the metadata values for the component.
Add the lightning__Tab target to the component’s configuration file.

Ex:
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="CustomSearchInLWC">
    <apiVersion>46.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
         <target>lightning__Tab</target>
    </targets>
</LightningComponentBundle>

Path:
From Setup, enter Tabs in the Quick Find box, and then click on New button in Lightning Components Tabs

 Then Select your LWC component.

Result

Tuesday, August 20, 2019

Custom search functionality in Lightning Web Component(lwc)

This post explains how to implement custom search functionality in Lightning web components(lwc).



Example

Apex Class
public inherited sharing class LWCExampleController {

    @AuraEnabled(Cacheable = true)
    public static list<Account> retriveAccs(String strAccName) {
        strAccName = '%' + strAccName + '%';
        list<Account> lstAccs = [SELECT  Id, Name, Industry, Phone, Type From Account WHERE Name LIKE :strAccName];

        if(lstAccs.isEmpty()) {
            throw new AuraHandledException('No Record Found..');
        }
        return lstAccs; 
    }
} 

CustomSearchInLWC.html
<template>
    <lightning-card title="Custom Search Functionality in LWC" icon-name="standard:account">
        <div if:true={errorMsg} style="margin-left: 3%;">
            <p style="color: red;">{errorMsg}</p>
        </div>

        <lightning-layout multiple-rows="true" vertical-align="end">
            <lightning-layout-item size="12" small-device-size="10" medium-device-size="8" large-device-size="6" padding="around-small">
                    <div class="slds-form-element">
                            <div class="slds-form-element__control">
                                    <lightning-input type="text" 
                                                     label="Enter Account Name" 
                                                     onchange={handleAccountName} ></lightning-input>
                            </div>
                        </div> 
            </lightning-layout-item>
            <lightning-layout-item size="12" small-device-size="2" medium-device-size="2" large-device-size="2" padding="around-small">
                    <lightning-button label="Search" 
                                      variant="brand" 
                                      onclick={handleSearch}></lightning-button>
                </lightning-layout-item>
            </lightning-layout><br/>

        <div if:true={searchData}>
            <lightning-datatable data={searchData} 
                                 columns={columns} 
                                 key-field="id"
                                 hide-checkbox-column="true"></lightning-datatable>
        </div>
    </lightning-card>

</template>

CustomSearchInLWC.js
import { LightningElement, track } from 'lwc';
import serachAccs from '@salesforce/apex/LWCExampleController.retriveAccs';

// datatable columns
const columns = [
    {
        label: 'Name',
        fieldName: 'AccName',
        type: 'url',
        typeAttributes: {label: { fieldName: 'Name' }, target: '_blank'}
    }, {
        label: 'Industry',
        fieldName: 'Industry',
    }, {
        label: 'Phone',
        fieldName: 'Phone',
        type: 'phone',
    }, {
        label: 'Type',
        fieldName: 'Type',
        type: 'text'
    },
];
export default class CustomSearchInLWC extends LightningElement {
    @track searchData;
    @track columns = columns;
    @track errorMsg = '';
    strSearchAccName = '';
    

    handleAccountName(event) {
        this.strSearchAccName = event.detail.value;
    }

    handleSearch() {
        if(!this.strSearchAccName) {
            this.errorMsg = 'Please enter account name to search.';
            this.searchData = undefined;
            return;
        }

        serachAccs({strAccName : this.strSearchAccName})
        .then(result => {
            result.forEach((record) => {
                record.AccName = '/' + record.Id;
            });

            this.searchData = result;
            
        })
        .catch(error => {
            this.searchData = undefined;
            window.console.log('error =====> '+JSON.stringify(error));
            if(error) {
                this.errorMsg = error.body.message;
            }
        }) 
    }

}

CustomSearchInLEC.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="CustomSearchInLWC">
    <apiVersion>46.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>

Output

Wednesday, August 14, 2019

How to get Default Record Type Id of object using apex in salesforce

In this example, I am getting Account object default record type Id

Example
Schema.DescribeSObjectResult describeResult = Account.getsObjectType().getDescribe();
List<Schema.RecordTypeInfo> rtInfos = describeResult.getRecordTypeInfos();
for(Schema.RecordTypeInfo rtInfo : rtInfos) {
    
    if(rtInfo.isDefaultRecordTypeMapping()) {       
        System.debug('Default Record Type Id ====> '+rtInfo.getRecordTypeId());
    }
}  

Result

Friday, August 9, 2019

How to make REST API Callout in Lightning Web Component(lwc)

This post explains how to make the callout in Lightning Web Components(lwc)

We can make the callout from Lightning Web Component in two ways
1. Client-side controller(JS controller)
2. Using the server-side controller(Apex Class)

In this demo, I am using https://www.alphavantage.co/
alpha vantage provides the following services for free
  •  Realtime and historical stock data 
  •  FX(Foreign exchange) and cryptocurrency feeds 
  •  50+ technical indicators 
  •  Global coverage

Get your free API Key https://www.alphavantage.co/support/#api-key

Endpoint URL : https://www.alphavantage.co

Make the Callout to Alpha Vantage and it sends the data in the form of JSON.
For more information Alpha Vantage Documentation 

In this demo, I am making the callout to check the foreign currency exchange rates.
Example endpoint URL:
https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency=USD&to_currency=INR&apikey=<API_KEY>

Sample JSON Response
{
    "Realtime Currency Exchange Rate": {
        "1. From_Currency Code": "USD",
        "2. From_Currency Name": "United States Dollar",
        "3. To_Currency Code": "INR",
        "4. To_Currency Name": "Indian Rupee",
        "5. Exchange Rate": "70.87700000",
        "6. Last Refreshed": "2019-08-09 14:01:57",
        "7. Time Zone": "UTC",
        "8. Bid Price": "70.86700000",
        "9. Ask Price": "70.88700000"
    }
}

Note
Make sure to white-list the endpoint URL based on your approach.

Client-side controller

Make sure your endpoint is white-list in Content Security Policies (CSP)
Path:
From Setup, enter CSP Trusted Sites in the Quick Find box, and then CSP Trusted Sites
Enter the endpoint URL and save.

Server-side controller

Add your endpoint URL in Remote Site settings

Path:
From Setup, enter Remote Site in the Quick Find box, and then Remote Site Settings

Once you white-listed the endpoint URL now we are ready to create the component.

Approach 1: Client-Side Controller

HTTPCalloutInLWC.html
<template>
    <lightning-card title="Realtime Currency Exchange Rate" icon-name="standard:currency">

        <lightning-layout multiple-rows="true" vertical-align="end">
        <lightning-layout-item size="12" small-device-size="4" medium-device-size="2" large-device-size="2" padding="around-small">
                <div class="slds-form-element">
                        <div class="slds-form-element__control">
                                <lightning-combobox title="Select Currency" 
                                                    label="From Base Currency"
                                                    value={fromCurrencyValue}
                                                    placeholder="-Select-"
                                                    options={options}
                                                    onchange={handleFromCurrencyChange}></lightning-combobox>
                        </div>
                    </div> 
            </lightning-layout-item>

            <lightning-layout-item size="12" small-device-size="4" medium-device-size="2" large-device-size="2" padding="around-small">
                    <div class="slds-form-element">
                            <div class="slds-form-element__control">
                                    <lightning-combobox title="Select Currency" 
                                                        label="To Currency"
                                                        value={toCurrencyValue}
                                                        placeholder="-Select-"
                                                        options={toCurrencyOptions}
                                                        onchange={handleToCurrencyChange}></lightning-combobox>
                            </div>
                        </div> 
            </lightning-layout-item>
            <lightning-layout-item size="12" small-device-size="2" medium-device-size="2" large-device-size="2" padding="around-small">
                    <lightning-button title="Currency Conversion" 
                                      label="Conversion Rate" 
                                      variant="brand" 
                                      onclick={handleCurrencyConversion}></lightning-button>
                </lightning-layout-item>
            </lightning-layout><br/>

            <template if:true={conversionData}>    
                <div class="slds-p-around_medium" id="modal-content-id-1">
                        <div style="font-size: 20px"><h1>Exchange rate from Currency <b>{fromCurrencyValue}</b> to <b>{toCurrencyValue}</b> </h1></div><br/>
                        <dl class="slds-list_horizontal slds-wrap">
                            <dt class="slds-item_label slds-truncate" title="From Currency Name">From Currency Name</dt>
                            <dd class="slds-item_detail slds-truncate"><b>: {conversionData.From_Currency_Name}</b></dd>
                            <dt class="slds-item_label slds-truncate" title="From Currency Code">From Currency Code</dt>
                            <dd class="slds-item_detail slds-truncate"><b>: {conversionData.From_Currency_Code}</b></dd>
                            <dt class="slds-item_label slds-truncate" title="To Currency Name">To Currency Name</dt>
                            <dd class="slds-item_detail slds-truncate"><b>: {conversionData.To_Currency_Name}</b></dd>
                            <dt class="slds-item_label slds-truncate" title="To Currency Code">To Currency Code</dt>
                            <dd class="slds-item_detail slds-truncate"><b>: {conversionData.To_Currency_Code}</b></dd>
                            <dt class="slds-item_label slds-truncate" title="Exchange Rate">Exchange Rate</dt>
                            <dd class="slds-item_detail slds-truncate">: <b style="color:red;">{conversionData.Exchange_Rate}</b></dd>
                            <dt class="slds-item_label slds-truncate" title="Last Refershed">Last Refereshed</dt>
                            <dd class="slds-item_detail slds-truncate"><b>: {conversionData.Last_Refershed}</b></dd>
                        </dl>
                </div>
            </template>
    </lightning-card>
</template>
HTTPCalloutInLWC.js
import { LightningElement, track} from 'lwc';

// Currency options
const options = [
                { label: 'USD', value: 'USD' },
                { label: 'EUR', value: 'EUR' },
                { label: 'CAD', value: 'CAD' },
                { label: 'GBP', value: 'GBP' },
                { label: 'INR', value: 'INR' }];

export default class HTTPCalloutInLWC extends LightningElement {
    @track fromCurrencyValue;
    @track toCurrencyValue;
    @track options = options;
    @track toCurrencyOptions = options;
    @track conversionData;
    
    // Getting Base currency value
    handleFromCurrencyChange(event) {
        this.fromCurrencyValue = event.detail.value;
    }

    // getting exchange currency value
    handleToCurrencyChange(event) {
        this.toCurrencyValue = event.detail.value;
    }


    // Making Callout using Fetch
    handleCurrencyConversion() {
        fetch('https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency=' 
                    + this.fromCurrencyValue + '&to_currency=' + this.toCurrencyValue + '&apikey=4W7NZUQNJ061YHHF', // End point URL
        {
            // Request type
            method:"GET",
            
            headers:{
                // content type
                "Content-Type": "application/json",
                // adding your access token 
                "Authorization": "OAuth 00DB0000000EfVQ!AQwAQEiiynMU2EsBcS2PhXSQ6KQTTG.Zr0hlDHTFcGcAPqKQOBNDB0rwyASZK44fqIAVe6GrVNZPsAWJ6iqXLNBfSQ.dqvW1",
            }
        })
        .then((response) => {
            return response.json(); // returning the response in the form of JSON
        })
        .then((jsonResponse) => {

            let objData = {
                From_Currency_Name : '',
                From_Currency_Code : '',
                To_Currency_Name : '',
                To_Currency_Code : '',
                Exchange_Rate : '',
                Last_Refersed : '',
            };

            window.console.log('jsonResponse ===> '+JSON.stringify(jsonResponse));
            // retriving the response data
            let exchangeData = jsonResponse['Realtime Currency Exchange Rate'];

            // adding data object
            objData.From_Currency_Code = exchangeData['1. From_Currency Code'];
            objData.From_Currency_Name = exchangeData['2. From_Currency Name'];
            objData.To_Currency_Code = exchangeData['3. To_Currency Code'];
            objData.To_Currency_Name = exchangeData['4. To_Currency Name'];
            objData.Exchange_Rate = exchangeData['5. Exchange Rate'];
            objData.Last_Refershed = exchangeData['6. Last Refreshed'];

            // adding data object to show in UI
            this.conversionData = objData;
        })
        .catch(error => {
            window.console.log('callout error ===> '+JSON.stringify(error));
        })
    } 

}
HTTPCalloutInLWC.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="HTTPCalloutInLWC">
    <apiVersion>46.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>

Approach 2: Server-Side Controller

To make the callout using server-side I created apex class it accepts the endpoint URL.

Apex Class
public inherited sharing class CurrencyConversionController {

    @AuraEnabled
    public static map<String, Object> retriveCurrencyConversionRates(String strEndPointURL){
        map<String, Object> mapJsonData = new map<String, Object>();
        String strResponse = null;
        if(String.isNotBlank(strEndPointURL)) {
            HttpRequest httpRequest = new HttpRequest();  
            httpRequest.setEndpoint(strEndPointURL);

            httpRequest.setMethod('GET');   
            httpRequest.setHeader('Authorization', 'OAuth ' + UserInfo.getSessionId());        
            httpRequest.setHeader('Authorization', 'Bearer ' + UserInfo.getSessionId()); 
            
            try {  
                Http http = new Http();   
                HttpResponse httpResponse = http.send(httpRequest);  

                while(httpResponse.getStatusCode() == 302) {
                    httpRequest.setEndpoint(httpResponse.getHeader('Location'));
                    httpResponse = new Http().send(httpRequest);
                }

                if (httpResponse.getStatusCode() == 200 ) {  
                    strResponse = httpResponse.getBody();  
                } 
                else {  
                    throw new CalloutException(httpResponse.getBody());  
                }   
            } 
            catch(Exception ex) {  
                throw ex;  
            }  
        } 

        if(!String.isBlank(strResponse)) {
            mapJsonData = (map<String, Object>)JSON.deserializeUntyped(strResponse);
            System.debug('mapJsonData ===> '+mapJsonData);
        }

        if(!mapJsonData.isEmpty()) {
            return mapJsonData;
        }
        else {
            return null;
        }
    }
}
Import the Apex class method in JS controller
import getCurrencyData from '@salesforce/apex/CurrencyConversionController.retriveCurrencyConversionRates';
update JS Controller with below code

HTTPCalloutInLWC.js
import { LightningElement, track} from 'lwc';

// importing apex class to make callout
import getCurrencyData from '@salesforce/apex/CurrencyConversionController.retriveCurrencyConversionRates';

// Currency options
const options = [
                { label: 'USD', value: 'USD' },
                { label: 'EUR', value: 'EUR' },
                { label: 'CAD', value: 'CAD' },
                { label: 'GBP', value: 'GBP' },
                { label: 'INR', value: 'INR' }];

export default class HTTPCalloutInLWC extends LightningElement {
    @track fromCurrencyValue;
    @track toCurrencyValue;
    @track options = options;
    @track toCurrencyOptions = options;
    @track conversionData;
    
    // Getting Base currency value
    handleFromCurrencyChange(event) {
        this.fromCurrencyValue = event.detail.value;
    }

    // getting exchange currency value
    handleToCurrencyChange(event) {
        this.toCurrencyValue = event.detail.value;
    }

    // Making Callout using apex class
    handleCurrencyConversion() {
        // endpoint URL
        let endpointURL = 'https://www.alphavantage.co/query?function=CURRENCY_EXCHANGE_RATE&from_currency=' 
                                + this.fromCurrencyValue + '&to_currency=' + this.toCurrencyValue + '&apikey=4W7NZUQNJ061YHHF';
        
        // calling apex class method to make callout
        getCurrencyData({strEndPointURL : endpointURL})
        .then(data => {
        
            let objData = {
                From_Currency_Name : '',
                From_Currency_Code : '',
                To_Currency_Name : '',
                To_Currency_Code : '',
                Exchange_Rate : '',
                Last_Refersed : '',
            };

            window.console.log('jsonResponse ===> '+JSON.stringify(data));
            // retriving the response data
            let exchangeData = data['Realtime Currency Exchange Rate'];

            // adding data object
            objData.From_Currency_Code = exchangeData['1. From_Currency Code'];
            objData.From_Currency_Name = exchangeData['2. From_Currency Name'];
            objData.To_Currency_Code = exchangeData['3. To_Currency Code'];
            objData.To_Currency_Name = exchangeData['4. To_Currency Name'];
            objData.Exchange_Rate = exchangeData['5. Exchange Rate'];
            objData.Last_Refershed = exchangeData['6. Last Refreshed'];

            // adding data object to show in UI
            this.conversionData = objData;
        })
        .catch(error => {
            window.console.log('error ====> '+JSON.stringify(error));
        })

    } 

}
Output

Thursday, August 8, 2019

How to get activity history of a object using SOQL in Salesforce

ActivityHistory is a standard object is displayed in a related list of closed activities—past events and closed tasks—related to an object.

SOQL Query
SELECT Id, (SELECT Id, Subject, CreatedDate FROM ActivityHistories WHERE CreatedDate = LAST_N_DAYS: 90) FROM Account WHERE Id = '001G000001uoKEL'
Result

Resource
https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_activityhistory.htm

Delete Record using Wire Service(uiRecordApi) in Lightning Web Component(lwc)

This post explains how to delete record using wire service(uiRecordApi) in lighting web components(lwc)

import { deleteRecord } from 'lightning/uiRecordApi' From scope module

In this demo, I am deleting account record using uiRecordApi.

Example

deleteRecordInLWC.html
<template>
    <div style="text-align: center;">
        <lightning-card title="Delete Record">
            <lightning-button label="Delete Record" onclick={handleDeleteRecord} variant="brand"></lightning-button>
        </lightning-card>
    </div>
</template>
deleteRecordInLWC.js
import { LightningElement, wire } from 'lwc';
// import uiRecordApi to delete record
import { deleteRecord } from 'lightning/uiRecordApi';

// importing to account record to delete
import getAccount from '@salesforce/apex/LWCExampleController.fetchAccount';

// importing to show to toast messages
import {ShowToastEvent} from 'lightning/platformShowToastEvent';

export default class DeleteRecordInLWC extends LightningElement {
    accRecord;

    // getting account record to delete
    @wire(getAccount)
    objAcc(result) {
        if (result.data) {
            this.accRecord = result.data;
        } 
        else if (result.error) {
            this.accRecord = undefined;
        }
    }
    
    // deleteing account record 
    handleDeleteRecord() {
        // passing account id to delete record
        // recordId is required value
        deleteRecord(this.accRecord.Id)
        .then(result => {
            window.console.log('result ====> '+result);
            this.dispatchEvent(new ShowToastEvent({
                title: 'Success!!',
                message: 'Account Deleted Successfully!!',
                variant: 'success'
            }),);
        })
        .catch(error => {
            this.dispatchEvent(new ShowToastEvent({
                title: 'Error!!',
                message: JSON.stringify(error),
                variant: 'error'
            }),);
        })
    }
}
deleteRecordInLWC.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="DeleteRecordInLWC">
    <apiVersion>46.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>
ApexClass
public inherited sharing class LWCExampleController {
    @AuraEnabled(Cacheable = true)
    public static Account fetchAccount() {
        Account objAcc =  [Select Id From Account Limit 1];
        return objAcc;
    }
}
Result



Resource
https://developer.salesforce.com/docs/component-library/documentation/lwc/lwc.reference_delete_record

Wednesday, August 7, 2019

How to get URL parameters in Lighting web componet(lwc)

This post explains how to read URL parameters in Lighting Web Components(lwc)

In this demo, I am using static URL if you want to get URL dynamically
Use window.location.href

Example URL:
http://www.example.com/index.php?id=1&image=awesome.jpg
// if you have Dynamic URL Use (window.location.href)
let testURL = 'http://www.example.com/index.php?id=1&image=awesome.jpg';

let newURL = new URL(testURL).searchParams;

console.log('id ===> '+newURL.get('id'));
console.log('image ====> '+newURL.get('image'));
Output


Monday, August 5, 2019

How to create a record using Wire service(uiRecordApi) in Lightning Web Component(lwc)

This post explains how to create a record using wire service(uiRecordApi) in Lightning Web Component(lwc).


Example

Import 'lightning/uiRecordApi' scope module in your component.

createRecordInLWC.html
<template>
    <lightning-card title="Create Account Record" icon-name="standard:account">
        <div style="margin-left: 6%" if:true={error}>
            <lightning-badge label={error} style="color: red;"></lightning-badge>
        </div>

        <template if:true={accRecord}>
            <div class="slds-m-around--xx-large">
                <div class="container-fluid">
                    <div class="form-group">
                        <lightning-input label="Enter Account Name" name="accName" required="required" type="text" value={accRecord.Name} onchange={handleNameChange}></lightning-input>
                    </div>
                    <div class="form-group">
                        <lightning-input label="Enter Phone Number" name="accPhone" type="text" value={accRecord.Phone} onchange={handlePhoneChange}></lightning-input>
                    </div>
                    <div class="form-group">
                        <lightning-input label="Enter Account Type" name="accEmail" required="required" type="text" value={accRecord.Type} onchange={handleTypeChange}></lightning-input>
                    </div>
                    <div class="form-group">
                        <lightning-input label="Enter Industry" name="accEmail" type="text" value={accRecord.Industry} onchange={handleIndustryChange}></lightning-input>
                    </div>
                </div>
                <br/>
                <lightning-button label="Submit" onclick={handleSave} variant="brand"></lightning-button>
            </div>
        </template>
    </lightning-card>
</template>
createRecordInLWC.js
import { LightningElement, track} from 'lwc';

// import uiRecordApi to create record
import { createRecord } from 'lightning/uiRecordApi';
// importing to show toast notifictions
import {ShowToastEvent} from 'lightning/platformShowToastEvent';

// importing Account fields
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import NAME_FIELD from '@salesforce/schema/Account.Name';
import Phone_FIELD from '@salesforce/schema/Account.Phone';
import Industry_FIELD from '@salesforce/schema/Account.Industry';
import Type_FIELD from '@salesforce/schema/Account.Type';

export default class CreateRecordInLWC extends LightningElement {
    @track error;

    // this object have record information
    @track accRecord = {
        Name : NAME_FIELD,
        Industry : Industry_FIELD,
        Phone : Phone_FIELD,
        Type : Type_FIELD
    };


    handleNameChange(event) {
        this.accRecord.Name = event.target.value;
        window.console.log('Name ==> '+this.accRecord.Name);
    }

    handlePhoneChange(event) {
        this.accRecord.Phone = event.target.value;
        window.console.log('Phone ==> '+this.accRecord.Phone);
        window.console.log('object ==> '+JSON.stringify(ACCOUNT_OBJECT));
    }

    handleTypeChange(event) {
        this.accRecord.Type = event.target.value;
        window.console.log('Type ==> '+this.accRecord.Type);
    }

    handleIndustryChange(event) {
        this.accRecord.Industry = event.target.value;
        window.console.log('Industry ==> '+this.accRecord.Industry);
    }


    handleSave() {
        const fields = {};

        fields[NAME_FIELD.fieldApiName] = this.accRecord.Name;
        fields[Phone_FIELD.fieldApiName] = this.accRecord.Phone;
        fields[Industry_FIELD.fieldApiName] = this.accRecord.Industry;
        fields[Type_FIELD.fieldApiName] = this.accRecord.Type;
       
        // Creating record using uiRecordApi
        let recordInput = { apiName: ACCOUNT_OBJECT.objectApiName, fields }
        createRecord(recordInput)
        .then(result => {
            // Clear the user enter values
            this.accRecord = {};

            window.console.log('result ===> '+result);
            // Show success messsage
            this.dispatchEvent(new ShowToastEvent({
                title: 'Success!!',
                message: 'Account Created Successfully!!',
                variant: 'success'
            }),);
        })
        .catch(error => {
            this.error = JSON.stringify(error);
        });
    }
}
createRecordInLWC.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="CreateRecordInLWC">
    <apiVersion>46.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>
Output

Generic Methods to Share sObject Record using Apex in Salesforce


Apex Class

public inherited sharing class SharingUtility {
    
    // For Standard Object Record
    public static list<SObject> createSharingForStandardObject(String strShareObjectName, String strParentField, map<Id, set<Id>> mapObjectIdUserIds, String strAccessLevelFieldName, String strAccessLevel, String strRowCause) {
        SObjectType objectType = Schema.getGlobalDescribe().get(strShareObjectName);
        list<SObject> lstObjects = new list<SObject>();
        
        for(Id objectId : mapObjectIdUserIds.keySet()) {
          for(Id userOrGroupId : mapObjectIdUserIds.get(objectId)) {
            SObject shareRecord = objectType.newsObject();
            shareRecord.put(strParentField, objectId);
            shareRecord.put('UserOrGroupId', userOrGroupId);
            shareRecord.put(strAccessLevelFieldName, strAccessLevel);
            shareRecord.put('RowCause', strRowCause);
            lstObjects.add(shareRecord);
          }
        }
        
        if(!lstObjects.isEmpty()) {
         insert lstObjects;
        }
       return lstObjects;
    }
    
    // For Custom Object Record
    public static void createSharingForCustomObject(String strShareObjectName, map<Id, set<Id>> mapObjectIdUserIds, String strAccessLevel, String strRowCause) {
        SObjectType objectType = Schema.getGlobalDescribe().get(strShareObjectName);
        list<SObject> lstObjects = new list<SObject>();
        
        for(Id objectId : mapObjectIdUserIds.keySet()) {
          for(Id userOrGroupId : mapObjectIdUserIds.get(objectId)) {
            SObject shareRecord = objectType.newsObject();
            shareRecord.put('ParentId', objectId);
            shareRecord.put('UserOrGroupId', userOrGroupId);
            shareRecord.put('AccessLevel', strAccessLevel);
            shareRecord.put('RowCause', strRowCause);
            lstObjects.add(shareRecord);
          }
        }
        
        if(!lstObjects.isEmpty()) {
         insert lstObjects;
        }
    }

}
Ex:
SharingUtility.createSharingForStandardObject('CaseShare', 'CaseId', new map<Id, set<Id>>{currentCase.Id => new set<Id>{currentCase.CreatedById}}, 'CaseAccessLevel', 'Edit', 'Manual');

Saturday, August 3, 2019

How to create record using apex in Lightning Web Components(lwc)

This post explains how to create the record in Lightning Web Components(lwc)

Example

createRecordInLWC.html
<template>
    <lightning-card title="Create Account Record" icon-name="standard:account">
        <div style="margin-left: 6%" if:true={error}>
            <lightning-badge label={error} style="color: red;"></lightning-badge>
        </div>

        <template if:true={accRecord}>
            <div class="slds-m-around--xx-large">
                <div class="container-fluid">
                    <div class="form-group">
                        <lightning-input label="Enter Account Name" name="accName" required="required" type="text" value={accRecord.Name} onchange={handleNameChange}></lightning-input>
                    </div>
                    <div class="form-group">
                        <lightning-input label="Enter Phone Number" name="accPhone" type="number" value={accRecord.Phone} onchange={handlePhoneChange}></lightning-input>
                    </div>
                    <div class="form-group">
                        <lightning-input label="Enter Account Type" name="accEmail" required="required" type="text" value={accRecord.Type} onchange={handleTypeChange}></lightning-input>
                    </div>
                    <div class="form-group">
                        <lightning-input label="Enter Industry" name="accEmail" type="text" value={accRecord.Industry} onchange={handleIndustryChange}></lightning-input>
                    </div>
                </div>
                <br/>
                <lightning-button label="Submit" onclick={handleSave} variant="brand"></lightning-button>
            </div>
        </template>
    </lightning-card>
</template>
createRecordInLWC.js
import { LightningElement, track} from 'lwc';

// Importing Apex Class method
import saveAccount from '@salesforce/apex/LWCExampleController.saveAccountRecord';

// importing to show toast notifictions
import {ShowToastEvent} from 'lightning/platformShowToastEvent';

// importing Account fields
import NAME_FIELD from '@salesforce/schema/Account.Name';
import Phone_FIELD from '@salesforce/schema/Account.Phone';
import Industry_FIELD from '@salesforce/schema/Account.Industry';
import Type_FIELD from '@salesforce/schema/Account.Type';

export default class CreateRecordInLWC extends LightningElement {
    @track error;

    // this object have record information
    @track accRecord = {
        Name : NAME_FIELD,
        Industry : Industry_FIELD,
        Phone : Phone_FIELD,
        Type : Type_FIELD
    };


    handleNameChange(event) {
        this.accRecord.Name = event.target.value;
        window.console.log('Name ==> '+this.accRecord.Name);
    }

    handlePhoneChange(event) {
        this.accRecord.Phone = event.target.value;
        window.console.log('Phone ==> '+this.accRecord.Phone);
    }

    handleTypeChange(event) {
        this.accRecord.Type = event.target.value;
        window.console.log('Type ==> '+this.accRecord.Type);
    }

    handleIndustryChange(event) {
        this.accRecord.Industry = event.target.value;
        window.console.log('Industry ==> '+this.accRecord.Industry);
    }


    handleSave() {
        saveAccount({objAcc: this.accRecord})
        .then(result => {
            // Clear the user enter values
            this.accRecord = {};

            window.console.log('result ===> '+result);
            // Show success messsage
            this.dispatchEvent(new ShowToastEvent({
                title: 'Success!!',
                message: 'Account Created Successfully!!',
                variant: 'success'
            }),);
        })
        .catch(error => {
            this.error = error.message;
        });
    }
}
Apex Class
public inherited sharing class LWCExampleController {

    @AuraEnabled
    public static void saveAccountRecord(Account objAcc){
        try{
            insert objAcc;
        }
        catch(Exception ex) {
            throw new AuraHandledException(ex.getMessage());
        }
    }
}
Result