Monday, February 4, 2019

Salesforce Lightning components interview questions


Salesforce Lightning components interview questions

1

Lightning vs ui namespace for components ?


It is recommended that you use the lightning namespace component. Beyond being equipped with the Lightning Design System styling, they handle accessibility, real-time interaction, and enhanced error messages.


LDS Styling
Enhanced error messages
Accessibility
Real time interaction

2

How to share code between multiple Lightning Components that aren't necessarily related to
each other.


We can use a Static Resource and include it in any components that need to share the same
JavaScript via ltng:require.

Service component pattern can also be used for this use case.

3

What is the difference between Lightning controller and helper ? The helper is designed to have shared code in it. So, you could have code shared by your
renderer and your controller or by multiple controller functions. That should go in the helper
JS file. It is a good practice to let the controller respond to events, possibly perform some amount of
control flow, and delegate business logic to the helper as a separation of concerns. It also sets
you up to be able to reuse your business logic in other parts of the component in the future. Helper code can be shared among components when they are related through inheritance.
If one component extends another it inherits its super component's helper and can override it. Helper functions improve code reuse, and move the heavy lifting of JavaScript logic away from
the client-side controller where possible. Implement event handling code in controller and delegate business logic code to helper. Anytime you need to call one controller function from another controller function, move that
logic to Helper.
Helper helps keep code in controller and renderer lean.
4
Is Lightning client side framework or server side ? The Lightning Component framework uses a stateful client and stateless server architecture
that relies on JavaScript on the client side to manage UI component metadata and application
data.
The client calls the server only when necessary, and the server only sends data that is
needed by the user to maximize efficiency.
Using JSON to exchange data between the server and the client, the framework intelligently
utilizes your server, browser, devices, and network so you can focus on the logic and
interactions of your apps.

5

How to show toast message in lightning component ?

var toastEvent = $A.get("e.force:showToast");

toastEvent.setParams({
            "title": title,
            "message": message,
            "type": type,
            "mode": "sticky",
            "duration": "50000"
        });

toastEvent.fire();

Does e.force:showToast work in preview mode ?

No, because the event is being handled by one.app, while its supported only in Lightning Experience, Salesforce1, and Lightning communities.

6

How to Validate That a component's label attribute Attribute Value Is Defined

var isDefined = !$A.util.isUndefined(cmp.get("v.label"));

How to Validate if a component's label attribute is empty

var isEmpty = $A.util.isEmpty(cmp.get("v.label"));

These two methods isUndefined and isEmpty of $A.util class can be used to check if an attribute is defined or not and if it is empty or not.

$A.util.isUndefined
$A.util.isEmpty

7

How would you clear or empty the current value of a components body

cmp.set("v.body", []);

How To replace the current value of a component's body with another component:

// newCmp is a reference to another component

cmp.set("v.body", newCmp);

8

How to append a new component to a component's body:

var body = cmp.get("v.body");
// newCmp is a reference to another new component
body.push(newCmp);
cmp.set("v.body", body);

9

How To prepend a new component to a component's body:

var body = cmp.get("v.body");
// newCmp is a reference to another new component
body.unshift(newCmp);
cmp.set("v.body", body);

10

How to remove a component from a component's body:

var body = cmp.get("v.body");
// Index (1) is zero-based so remove the second component in the body
body.splice(1, 1);
cmp.set("v.body", body);

11

ui:button vs lightning:button ? which one should you prefer to use and why ?

One should prefer to use lightning:button since it comes with LDS styling and salesforce intends to deprecate ui:button(components with ui namespace).

ui:button has a press attribute while lightning:button has an onClick attribute. Both have aura:id

<ui:button aura:id="button1" label="Click me" press="{!c.nameThatButton}"/>

<lightning:button aura:id="button1" name="buttonname1" label="Click me" onclick="{!c.nameThatButton}"/>

12

How to find out which button was pressed ?

<aura:component>

    <aura:attribute name="whichButton" type="String" />
 
    <p>You clicked: {!v.whichButton}</p>

    <ui:button aura:id="button1" label="Click me" press="{!c.nameThatButton}"/>
    <ui:button aura:id="button2" label="Click me too" press="{!c.nameThatButton}"/>

</aura:component>


({
    nameThatButton : function(cmp, event, helper) {
        var whichOne = event.getSource().getLocalId();
        console.log(whichOne);
        cmp.set("v.whichButton", whichOne);
    }
})


13

event.getSource().getLocalId() returns the aura:id of the clicked button.
event.getSource().get("v.name") returns the name of the clicked button.

14

How can you add or remove a CSS style on a component or element during runtime.

To retrieve the class name on a component, use component.find('myCmp').get('v.class'), where myCmp is the aura:id attribute value.

component.find('myCmp').get('v.class');

To append and remove CSS classes from a component or element, use the $A.util.addClass(cmpTarget, 'class') and $A.util.removeClass(cmpTarget, 'class') methods.

$A.util.addClass(cmpTarget, 'class');
$A.util.removeClass(cmpTarget, 'class');

15

Adding and removing CSS class from component example

<aura:component>
    <div aura:id="changeIt">Change Me!</div><br />
    <lightning:button onclick="{!c.applyCSS}" label="Add Style" />
    <lightning:button onclick="{!c.removeCSS}" label="Remove Style" />
</aura:component>

CSS source

.THIS.changeMe {
    background-color:yellow;
    width:200px;
}

Client-side controller source

{
    applyCSS: function(cmp, event) {
        var cmpTarget = cmp.find('changeIt');
        $A.util.addClass(cmpTarget, 'changeMe');
    },
 
    removeCSS: function(cmp, event) {
        var cmpTarget = cmp.find('changeIt');
        $A.util.removeClass(cmpTarget, 'changeMe');
    }
}

cmp.find() locates the component using the local ID, denoted by aura:id="changeIt" in this demo.

16

How will you toggle a CSS class on a component ?

To toggle a class, use $A.util.toggleClass(cmp, 'class'), which adds or removes the class.

The cmp parameter can be component or a DOM element. Preferably it should be a component.

To conditionally set a class for an array of components, pass in the array to $A.util.toggleClass().

mapClasses: function(arr, cssClass) {
    for(var cmp in arr) {
        $A.util.toggleClass(arr[cmp], cssClass);
    }
}

17

How to Dynamically Show or Hide Markup

$A.util.toggleClass(cmp, 'class')

You can use CSS to toggle markup visibility. However, <aura:if> is the preferred approach because it defers the creation and rendering of the enclosed element tree until needed.

This example uses $A.util.toggleClass(cmp, 'class') to toggle visibility of markup.

<!--c:toggleCss-->

<aura:component>
    <lightning:button label="Toggle" onclick="{!c.toggle}"/>
    <p aura:id="text">Now you see me</p>
</aura:component>


/*toggleCssController.js*/
({
    toggle : function(component, event, helper) {
        var toggleText = component.find("text");
        $A.util.toggleClass(toggleText, "toggle");
    }
})


/*toggleCss.css*/
.THIS.toggle {
    display: none;
}

18

What is more preferred way for Conditional display of Markup, <aura:if isTrue="" /> vs $A.util.toggleClass(cmp, "");

Best Practices for Conditional Markup

Using the <aura:if> tag is the preferred approach to conditionally display markup but there are alternatives. Consider the performance cost and code maintainability when you design components. The best design choice depends on your use case.

Conditionally Create Elements with <aura:if>

Let's look at a simple example that shows an error message when an error occurs.

<aura:if isTrue="{!v.isError}">
    <div>{!v.errorMessage}</div>
</aura:if>

The <div> component and its contents are only created and rendered if the value of the isTrue expression evaluates to true. If the value of the isTrue expression changes and evaluates to false, all the components inside the <aura:if> tag are destroyed. The components are created again if the isTrue expression changes again and evaluates to true.

The general guideline is to use <aura:if> because it helps your components load faster initially by deferring the creation and rendering of the enclosed element tree until the condition is fulfilled.

Toggle Visibility Using CSS

You can use CSS to toggle visibility of markup by calling $A.util.toggleClass(cmp, 'class') in JavaScript code.

Elements in markup are created and rendered up front, but they're hidden.

The conditional markup is created and rendered even if it's not used, so <aura:if> is preferred.

Dynamically Create Components in JavaScript

You can dynamically create components in JavaScript code. However, writing code is usually harder to maintain and debug than using markup. Again, using <aura:if> is preferred but the best design choice depends on your use case.

19

What is main difference between Application and Component Events ?

Component events: to talk to a parent using the capture and bubbling mechanism, like with DOM events.

Application events: to broadcast to other components and not exclusively ancestors. Applications events can talk to many components that can be interested by the event.

20

Can Lightning Web Components contain Aura components ?

No, Lightning web components can't contain Aura components.

Aura components can contain Lightning web components.
Lightning web components can't contain Aura components.

21

Which Aura components are good candidate to be migrated to Lightning web component ?

An Aura component whose performance is critical (UI renders slowly) is a good candidate to migrate to a Lightning web component.

22.

What are some key features of Lightning Web Components ?

A.

Modern JavaScript

HTML Templates
ES6
Web components
Custom Elements

B.

Code Performance

Because more features are executed natively by the browser instead of by a JavaScript framework. Rendering time for your components will be quicker.

C.

Developer Productivity and Satisfaction

Working with standard JavaScript, HTML, and CSS and even accessing proprietary pieces (components and APIs that make it easier to work with Salesforce) in a standard way.


Monday, January 21, 2019

Create record using Lightning Data Service in Lightning Component

Create record using Lightning Data Service in Lightning Component


CreateContactQuicklyApp.app

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


CreateContactQuickly.cmp

<aura:component implements="force:appHostable, flexipage:availableForAllPageTypes,
                            force:hasRecordId" access="global" >

    <!--flexipage:availableForRecordHome-->
    <aura:attribute name="newContact" type="Object"/>
    <aura:attribute name="simpleNewContact" type="Object"/>
    <aura:attribute name="newContactError" type="String"/>

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

    <force:recordData aura:id="contactRecordCreator"
        layoutType="FULL"
        targetRecord="{!v.newContact}"
        targetFields="{!v.simpleNewContact}"
        targetError="{!v.newContactError}" />
 
    <!-- Display the new contact form -->
    <div class="Create Contact">
        <lightning:card iconName="action:new_contact" title="Create Contact">
            <div class="slds-p-horizontal--small">

            <br/>
            <br/>
            <lightning:input aura:id="inputFirstName" type="text" label="First Name" value="{!v.simpleNewContact.FirstName}" />
            <br/>         
            <lightning:input aura:id="inputLastName" type="text" label="Last Name" value = "{!v.simpleNewContact.LastName}" />
        <br/>
            <lightning:input aura:id="inputDeptName" type="text" label="Department" value="{!v.simpleNewContact.Department}" />
            <br/>
            <lightning:button aura:id="buttonApply" label="Create Contact"  variant="brand" onclick="{!c.handleSaveContact}"/>
            <br/>

            </div>
        </lightning:card>
    </div>
 
    <!-- Display Lightning Data Service errors -->
    <aura:if isTrue="{!not(empty(v.newContactError))}">
            <div class="recordError">
                {!v.newContactError}</div>
    </aura:if>

</aura:component>


CreateContactQuicklyController.js

({
    doInit: function(component, event, helper) {
        // Prepare a new record from template
        component.find("contactRecordCreator").getNewRecord(
            "Contact", // sObject type (objectApiName)
            null,      // recordTypeId
            false,     // skip cache?
            $A.getCallback(function() {
                var rec = component.get("v.newContact");
                var error = component.get("v.newContactError");
                if(error || (rec === null)) {
                    console.log("Error initializing record template: " + error);
                    return;
                }
                console.log("Record template initialized: " + rec + "  " + rec.sobjectType);
            })
        );
    },
    handleSaveContact : function(component, event, helper) {

        var inputFieldFirstName = component.find("inputFirstName");
        if(inputFieldFirstName != null) {
            var fname = inputFieldFirstName.get("v.value");
            console.log('Value of First Name is ' + fname);
        } else {
            console.log('inputField for first name is null');
        }
   
        var inputFieldDeptName = component.find("inputDeptName");
        if(inputFieldDeptName != null) {
            var dept = inputFieldDeptName.get("v.value");
            console.log('Value of Department is ' + dept);
        } else {
            console.log('inputField for Department is null');
        }
   
        var inputFieldLastName = component.find("inputLastName");
        if(inputFieldLastName != null) {
            var lname = inputFieldLastName.get("v.value");
            console.log('Value of Last Name is ' + lname);
        } else {
            console.log('inputField for last name is null');
        }
   
        console.log(inputFieldFirstName.get('v.validity').valid);
   
        if($A.util.isEmpty(fname)) {
            inputFieldFirstName.setCustomValidity("You must enter a value for First Name.");
            inputFieldFirstName.reportValidity();
        } else {
            inputFieldFirstName.setCustomValidity("");
            inputFieldFirstName.reportValidity();
            console.log(inputFieldFirstName.get('v.validity').valid);
        }
   
        console.log(inputFieldLastName.get('v.validity').valid);
   
        if ($A.util.isEmpty(lname)) {
            inputFieldLastName.setCustomValidity("You must enter a value for Last Name.");
            inputFieldLastName.reportValidity();
        } else {
            inputFieldLastName.setCustomValidity("");
            inputFieldLastName.reportValidity();
            console.log(inputFieldLastName.get('v.validity').valid);
        }

        //component.set("v.simpleNewContact.AccountId", component.get("v.recordId"));
        component.find("contactRecordCreator").saveRecord(function(saveResult) {
            console.log('saveResult out of saveRecord ' + saveResult);
            if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
                // record is saved successfully
                console.log('saveResult state ' + saveResult.state);
             
                component.find("contactRecordCreator").getNewRecord(
                    "Contact", // sObject type (objectApiName)
                    null,      // recordTypeId
                    false,     // skip cache?
                    $A.getCallback(function() {
                        var rec = component.get("v.newContact");
                        var error = component.get("v.newContactError");
                        if(error || (rec === null)) {
                            console.log("Error initializing record template: " + error);
                            return;
                        }
                        console.log("Record template initialized: " + rec + "  " + rec.sobjectType);
                    })
                );
             
                var resultsToast = $A.get("e.force:showToast");
                resultsToast.setParams({
                    "title": "Saved",
                    "message": "The record was saved."
                });
                resultsToast.fire();

            } else if (saveResult.state === "INCOMPLETE") {
                // handle the incomplete state
                console.log("User is offline, device doesn't support drafts.");
            } else if (saveResult.state === "ERROR") {
                // handle the error state
                console.log('Problem saving contact, error: ' + JSON.stringify(saveResult.error));
            } else {
                console.log('Unknown problem, state: ' + saveResult.state + ', error: ' + JSON.stringify(saveResult.error));
            }
        });
    }
})


Tabs > Lightning Component based tab > Create new tab > Quick_Create_Contact

Add tab to Sales app.

Tuesday, November 20, 2018

Lightning Base component Input text validation example in Lightning Component.

Lightning Base component <lightning:input type="text" /> Input text validation example


Lightning Base component <lightning:input type="text" /> Input text validation example

Capturing component markup UI values in component JS controller.
Doing some validation on input text entered and displaying error message.


Application markup

InputCompValidation.app

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

Component Markup

InputValidation.cmp

<aura:component implements="flexipage:availableForAllPageTypes" access="global" >
 
    <aura:attribute name="firstName" type="String" />
    <aura:attribute name="lastName" type="String" />
    <aura:attribute name="midName" type="String" />
 
    <br/>
    <br/>
    <lightning:input aura:id="inputFirstName" type="text" label="First Name" value="{!v.firstName}"  />
    <br/>
    <lightning:input aura:id="inputMidName" type="text" label="Middle Name" value="{!v.midName}"  />
    <br/>
    <lightning:input aura:id="inputLastName" type="text" label="Last Name" value = "{!v.lastName}" />
 
    <br/>
    <br/>
 
    <lightning:button aura:id="buttonApply" label="Apply"  variant="brand" onclick="{!c.check}"/>
 
</aura:component>

Client side JS Controller

InputValidationController.js

({
    check : function(component, event, helper) {

        var inputFieldFirstName = component.find("inputFirstName");
        if(inputFieldFirstName != null) {
            var fname = inputFieldFirstName.get("v.value");
            console.log('Value of First Name is ' + fname);
        } else {
            console.log('inputField for first name is null');
        }
     
        var inputFieldMidName = component.find("inputMidName");
        if(inputFieldMidName != null) {
            var mname = inputFieldMidName.get("v.value");
            console.log('Value of Middle Name is ' + mname);
        } else {
            console.log('inputField for mid name is null');
        }
     
        var inputFieldLastName = component.find("inputLastName");
        if(inputFieldLastName != null) {
            var lname = inputFieldLastName.get("v.value");
            console.log('Value of Last Name is ' + lname);
        } else {
            console.log('inputField for last name is null');
        }
     
        console.log(inputFieldFirstName.get('v.validity').valid);
     
        if($A.util.isEmpty(fname)) {
            inputFieldFirstName.setCustomValidity("You must enter a value for First Name.");
            inputFieldFirstName.reportValidity();
        } else {
            inputFieldFirstName.setCustomValidity("");
            inputFieldFirstName.reportValidity();
            console.log(inputFieldFirstName.get('v.validity').valid);
        }
     
        console.log(inputFieldLastName.get('v.validity').valid);
     
        if ($A.util.isEmpty(lname)) {
            inputFieldLastName.setCustomValidity("You must enter a value for Last Name.");
            inputFieldLastName.reportValidity();
        } else {
            inputFieldLastName.setCustomValidity("");
            inputFieldLastName.reportValidity();
            console.log(inputFieldLastName.get('v.validity').valid);
        }
    }
})

Wednesday, July 18, 2018

Lightning component with configurable attributes

Lightning component with configurable attributes

Component

<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,
                            force:hasSObjectName" access="global">

    <aura:attribute name="recordId" type="Id" default="" />
    <aura:attribute name="sObjectName" type="String" default="Account" />
    <aura:attribute name="numberOfColumns" type="String" default="2" />
    <aura:attribute name="fieldsArray" type="String" />
    <aura:attribute name="layoutType" type="String" default="Compact" />

    <lightning:card iconName="custom:custom19" title="lightning:recordForm in Spring'18">

        <div class="slds-p-left_large slds-p-right_medium">
       
            <lightning:recordForm aura:id="recordViewForm"
                                  recordId="{!v.recordId}"
                                  objectApiName="{!v.sObjectName}"
                                  fields="{!v.fieldsArray}"
                                  layoutType="{!v.layoutType}"
                                  columns="{!v.numberOfColumns}"
                                  onsuccess="{!c.raiseTheToastMessage}" />
        </div>
   
    </lightning:card>
</aura:component>

Design file

<design:component>
    <design:attribute name="sObjectName" label="Object" datasource = "Account, Contact, Opportunity" description="object on whose detail page component should be available" />
    <design:attribute name="numberOfColumns" label="Columns" datasource="1,2,3,4" description="Number of columns component should have" />
    <design:attribute name="fieldsArray" label="Field List" description="comma separated list of fields" /> 
    <design:attribute name="layoutType" label="Layout" datasource = "Custom, Full, Compact" description="type of layout to be used in component" /> 
</design:component>


JS Controller


({
    raiseTheToastMessage : function(component, event, helper) {
        var toastEvent = $A.get("e.force:showToast");
        toastEvent.setParams({
            "title": "Success!",
            "message": "The record has been updated successfully.",
            "type": "success"
        });
        toastEvent.fire();
    }
})

Tuesday, July 10, 2018

Lightning Component using lightning:recordForm


Lightning component which can be used on Record detail page to provide a user a quick view on important fields. This uses component <lightning:recordForm> which is displayed inside a <lightning:card>. <aura:attribute> are used to pass values to attributes of <lightning:recordForm> component.

Component Code :

<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,
                            force:hasSObjectName" access="global">

    <aura:attribute name="recordId" type="Id" default="" />
    <aura:attribute name="sObjectName" type="String" default="Account" />
    <aura:attribute name="layoutType" type="String" default="Compact" />
    <aura:attribute name="numberOfColumns" type="String" default="2" />
    <aura:attribute name="compMode" type="String" default="Edit" />
    <aura:attribute name="fieldsArray" type="String[]" default="['AccountNumber','Name','AccountSource','Description',
                                                'NumberOfEmployees','Industry','Phone','Type','Rating']" />

    <lightning:card iconName="custom:custom19" title="lightning:recordForm in Spring'18">
 
        <div class="slds-p-left_large slds-p-right_medium">
         
            <lightning:recordForm aura:id="recordViewForm"
                                  recordId="{!v.recordId}"
                                  objectApiName="{!v.sObjectName}"
                                  fields="{!v.fieldsArray}"
                                  columns="{!v.numberOfColumns}"
                                  layoutType="{!v.layoutType}"
                                  mode="{!v.compMode}"
                                  onsuccess="{!c.raiseTheToastMessage}"
                                  onload="{!c.onLoad}"
                                  onerror="{!c.onError}" />
        </div>
     
    </lightning:card>
</aura:component>



Client side JS Controller code


({
    raiseTheToastMessage : function(component, event, helper) {
        var toastEvent = $A.get("e.force:showToast");
        toastEvent.setParams({
            "title": "Success!",
            "message": "The record has been updated successfully.",
            "type": "success"
        });
        toastEvent.fire();
    },
    onLoad : function(component, event, helper) {
        var toastEvent = $A.get("e.force:showToast");
        toastEvent.setParams({
            "title": "Loaded!",
            "message": "The record has been Loaded successfully ."
        });
        toastEvent.fire();
    },
    onError : function(component, event, helper) {
        var toastEvent = $A.get("e.force:showToast");
        toastEvent.setParams({
            "title": "Error!",
            "message": "Error."
        });
        toastEvent.fire();
    }
})






Sunday, July 8, 2018

Lightning Component using lightning:recordForm

This component is intended to be used on Contact Object detail page.
This component uses lightning:recordForm component.
It takes contact record id and provides a little form where you choose the fields you want to display and allows you to view / edit those fields.

Component Code:

<aura:component implements="flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,force:hasSObjectName" access="global">

    <aura:attribute name="recordId" type="Id" default="" />
    <aura:attribute name="sObjectName" type="String" default="Contact" />
    <aura:attribute name="fieldsToDisplay" type="String" />
    <aura:attribute name="val" type="String" />
    <aura:attribute name="layoutType" type="String" default="Custom" />
    <aura:attribute name="numberOfColumns" type="String" default="1" />
    <aura:attribute name="fieldsArray" type="String[]" default="['Name','Email','Phone','AccountId']" />
    <aura:attribute name="targetFields" type="Contact" />

    <lightning:card iconName="custom:custom19" title="lightning:recordForm in Spring'18">
 
        <div class="slds-p-left_large slds-p-right_medium">
         
            <lightning:recordForm aura:id="recordViewForm"
                                  recordId="{!v.recordId}"
                                  objectApiName="{!v.sObjectName}"
                                  fields="{!v.fieldsArray}"
                                  columns="1"
                                  onsuccess="{!c.happyDance}" />
        </div>
     
    </lightning:card>
</aura:component>

JS Controller Code:

({
    happyDance : function(component, event, helper) {
        var toastEvent = $A.get("e.force:showToast");
        toastEvent.setParams({
            "title": "Success!",
            "message": "The record has been updated successfully.",
            "type": "success"
        });
        toastEvent.fire();
    }
})

Sunday, May 27, 2018

Apex Record Sharing

Apex Sharing


Individual records can be shared with Users or Groups by creating records in share object related to the object. These records can be inserted in share object from trigger or controller.

We will need to create records in share object when object's default OWD settings are restricted like Private, Public Read Only etc. This will open up record level access to new users / groups.

Fields to be set while using Apex sharing: ParentId, UserOrGroupId, AccessLevel, RowCause

These fields must be set when creating records in Share object :

  • ParentId
  • UserOrGroupId
  • AccessLevel
  • RowCause


ParentId The Id of the record being shared. This field cannot be updated.

UserOrGroupId The Id of the User to whom you are granting access. May also be a
Public Group Id. When sharing to a role, you cannot assign Role Id to UserOrGroupId field
directly. It should instead be a matching Group Id from Group table. This field cannot be
updated.

RowCause (aka Sharing Reasons) The reason why the user or group is being granted access.
The reason determines the type of sharing, which in turn controls who can alter the
sharing record. This field cannot be updated.

AccessLevel The level of access that the specified User or Group has been granted.
Valid values for Apex managed sharing are: Edit, Read.

This field must be set to an access level that is higher than the organizations default
access level for the parent object. For more information, see Access Levels.

AccessLevel is the only updateable field in Share object record.

Contact object has a custom field named Make_Public__c.

If a new contact record is either being created or updated and if this custom checkbox field is set to true, share the contact record with Group named Organization.

trigger ContactMakePublicTrigger on Contact (after insert, after update) {

  // get the id for the group for everyone in the org
  ID groupId = [select id from Group where Type = 'Organization'].id;
  // inserting new records
  if (Trigger.isInsert) {

    List<ContactShare> sharesToCreate = new List<ContactShare>();

    for (Contact contact : Trigger.new) {
      if (contact.Make_Public__c == true) {
        // create the new share for group
        ContactShare cs = new ContactShare();
        cs.ContactAccessLevel = 'Edit';
        cs.ContactId = contact.Id;
        cs.UserOrGroupId =  groupId;
        sharesToCreate.add(cs);
      }
    }

    // do the DML to create shares
    if (!sharesToCreate.isEmpty())
      insert sharesToCreate;

  // updating existing records
  } else if (Trigger.isUpdate) {

    List<ContactShare> sharesToCreate = new List<ContactShare>();
    List<ID> shareIdsToDelete = new List<ID>();

    for (Contact contact : Trigger.new) {

      // if the record was public but is now private -- delete the existing share
      if (Trigger.oldMap.get(contact.id).Make_Public__c == true &&
  contact.Make_Public__c == false) {
        shareIdsToDelete.add(contact.id);

      // if the record was private but now is public -- create the new share for the group
      } else if (Trigger.oldMap.get(contact.id).Make_Public__c == false &&
  contact.Make_Public__c == true) {

        // create the new share with read/write access
        ContactShare cs = new ContactShare();
        cs.ContactAccessLevel = 'Edit';
        cs.ContactId = contact.Id;
        cs.UserOrGroupId =  groupId;
        sharesToCreate.add(cs);
      }
    }

    // do the DML to delete shares
    if (!shareIdsToDelete.isEmpty())
      delete [select id from ContactShare where ContactId IN :shareIdsToDelete
and RowCause = 'Manual'];
    // do the DML to create shares
    if (!sharesToCreate.isEmpty())
      insert sharesToCreate;

  }

}

Salesforce Lightning components interview questions

Salesforce Lightning components interview questions 1 Lightning vs ui namespace for components ? It is recommended that you use t...