Skip to content

therishabh/wipro-salesforce

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

54 Commits
 
 

Repository files navigation

Wipro Salesforce interview Questions

Summary

Question : What all asynchronous process available in salesforce. Question : Explain batch processing
Question : Best Practices follwed for apex
Question : Best practices follwed for triggeres.
Question : How to connect two systems (Integartion related questions - Connected app, named credentials)
Question : Different types of flows.
Question : What is the maximum number of records that can be processed by a trigger?
Question : Context variables in triggers
Question : Future method and Quable methods (Limitation, which senario you will go for future menthod)
Question : How to set field level security in Apex (WITH SECURITY_ENFORCED)?
Question : Best Practices for flows (Avoid hard code values, mixed DMLs, Avoid DML statements inside Loop, Error handling etc).
Question : Mixed DML exception(Future method)
Question : Schedulable classes can we do callouts directly from schedulable class or not.
Question : Imaging you are processing a batch fo 50000 and you have to seprate the process sucessful and failed record, how you will achieve it.
Question : Questions related to field level security.
Question : Database stateful and stateless (Difference and senario if you faced any)
Question : How to pass the values from flow to Apex.
Question : Field restriction by apex
Question : application event in LWC
Question : life cycle of LWC
Question : Named credential
Question : Mixed DML exception
Question : Open Id connect for integration
Question : Calling one batch to another batch
Question : Is there a way to callout triggers
Question : About recursive triggers
Question : Reason for bulkification of your code
Question : Database operation and syntax
Question : What are public component in LWC
Question : Types of decorators in LWC
Question : Difference between, trigger.old and Trigger.oldmap
Question : Not using @future annotation in webservices callout, what will happen
Question : How can you implement recursive trigger in salesforce
Question : Composite request
Question : Component event and application event difference
Question : What is LDS(Lightning Data Services) in lwc
Question : SOQL 101 Exception
Question : Nested aura component can we have, which event will execute first
Question : Deployment tool.. CI/CD process.. how to setup
Question : explain one LWC component created by you.
Question : How will you get the data from Apex to LWC
Question : how many ways we can query the data
Question : What is Wire method
Question : Concept of promises in LWC ?
Question : how to establish communication between components
Question : Integration - breif what you have done.
Question : diff between userflow and web server flow ( connected App authorization)?
Question : serve side - how the authentication is happen?
Question : Platform event?
Question : Managed Package - exp
Question : Aura - share the method with another Aura comp?
Question : styling hooks in LWC?
Question : have you worked in service window.runnerWindow.proxyConsole.
Question : How did you do deployment
Question : Involved in any deployment
Question : Can we use multiple decorators for one property
Question : what is the need of LWC, when we are already having Aura
Question : How will you overcome the governor limit
Question : How to call from one batch class into another batch class
Question : Why apex callout is always asyc
Question : SECURITY_ENFORCE use in SOQL
Question : Security question on Triggers
Question : Can we pass one batch data to another batch process
Question : Types of Async classes
Question : About Iterable class in Batchable
Question : PMD violations
Question : Devops process
Question : Imperative apex
Question : Difference between aura and LWC component
Question : Types of Events in AURA

Question : What all asynchronous process available in salesforce.

Answer :

Salesforce provides several asynchronous processing options to handle operations that require large volumes of data, complex processing, or tasks that should not be performed in a synchronous transaction. Here's a comprehensive list of asynchronous processes available in Salesforce:

  1. Future Methods
  2. Batch Apex
  3. Scheduled Apex
  4. Queueable Apex
  5. Apex REST Callouts

1. Future Methods

  • Use Case: Perform long-running operations or callouts to external services without blocking the main thread.
  • Key Points:
    • Methods annotated with @future.
    • Limited to 50 future method calls per Apex invocation.
    • Future methods cannot return values.
    • Cannot be chained.

Example

public class FutureMethodExample {
    @future(callout=true)
    public static void callExternalService() {
        // Callout code
    }
}

2. Batch Apex

  • Use Case: Process large volumes of records asynchronously.
  • Key Points:
    • Implement Database.Batchable interface.
    • Can handle millions of records.
    • Allows for stateful processing using Database.Stateful.

Example

public class BatchApexExample implements Database.Batchable<SObject> {
    public Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator('SELECT Id, Name FROM Account');
    }
    public void execute(Database.BatchableContext BC, List<SObject> scope) {
        // Process each batch of records
    }
    public void finish(Database.BatchableContext BC) {
        // Final operations
    }
}

3. Scheduled Apex

  • Use Case: Schedule a batch job or other Apex code to run at specific times.
  • Key Points:
    • Implement Schedulable interface.
    • Use System.schedule to schedule the job.

Example

public class ScheduledApexExample implements Schedulable {
    public void execute(SchedulableContext SC) {
        // Code to execute
    }
}

// Schedule the job
System.schedule('Job Name', '0 0 12 * * ?', new ScheduledApexExample());

4. Queueable Apex

  • Use Case: Chain jobs and perform complex operations asynchronously.
  • Key Points:
    • Implement Queueable interface.
    • Supports job chaining.
    • More flexible than future methods.

Example

public class QueueableApexExample implements Queueable {
    public void execute(QueueableContext context) {
        // Code to execute
    }
}

// Enqueue the job
Id jobId = System.enqueueJob(new QueueableApexExample());

5. Apex REST Callouts

  • Use Case: Make HTTP requests to external services asynchronously.
  • Key Points:
    • Use @future(callout=true) for asynchronous callouts.
    • Can be combined with future methods or Queueable Apex.

Example

public class RestCalloutExample {
    @future(callout=true)
    public static void makeCallout() {
        HttpRequest req = new HttpRequest();
        req.setEndpoint('https://example.com/api');
        req.setMethod('GET');
        Http http = new Http();
        HttpResponse res = http.send(req);
    }
}

Question : Explain batch processing

Answer :

https://github.com/therishabh/salesforce-apex/blob/main/README.md#batch-apex


Question : Best Practices follwed for apex

Answer :

https://www.salesforceben.com/12-salesforce-apex-best-practices/

1. Bulkify Your Code

Bulkification of your code is the process of making your code able to handle multiple records at a time efficiently.

2. Avoid DML/SOQL Queries in Loops

SOQL and DML are some of the most expensive operations we can perform within Salesforce Apex, and both have strict governor limits associated with them.

3. Avoid Hard-Coded IDs

4. Explicitly Declare Sharing Model

When we begin writing a brand-new class, one of the first things we should do is declare our sharing model. If we require our code to bypass record access, we must always declare without sharing, but when we want it to enforce sharing rules, developers can often find themselves skipping this step.

5. Use a Single Trigger per SObject Type

6. Use SOQL for Loops

When we query a large set of records and assign the results to a variable, a large portion of our heap can be consumed.

7. Test Multiple Scenarios

Salesforce mandates that we have at least 75% code coverage when we wish to deploy Apex code into production, and while having a high number of lines covered by tests is a good goal to have, it doesn’t tell the whole story when it comes to testing.

Writing tests only to achieve the code coverage requirement shows one thing: your code has been run, and it doesn’t actually provide any value other than showing that in a very specific scenario (which may or may not ever happen in practice!).

When writing our tests, we should worry about code coverage less, and instead concern ourselves with covering different use cases for our code, ensuring that we’re covering the scenarios in which the code is actually being run. We do this by writing multiple test methods, some of which may be testing the same methods and not generating additional covered lines, each of which runs our code under a different scenario.

8. Avoid Nested Loops

Loops inside of loops – sometimes it can’t be avoided. You simply need to iterate over one thing related to another. Good stuff, right? While there may not seem to be anything immediately wrong here, and the code could very well run perfectly fine without running into performance issues or governor limits, the issue here is more one of maintainability and readability. image

Rather than using nested loops, a good strategy is to abstract your logic into separate methods (which perform the logic themselves). This way, when we’re looking at a block of code from a higher level, it is far easier to understand. Abstracting our code out like this also has other benefits, such as making it easier to test specific aspects of our code. image

9. Have a Naming Convention

Naming conventions tend to be a hot topic in any developer team. The benefits are clear if everyone follows them, as they make it easier for other people in your team to understand what’s going on within an org.

10. Avoid Business Logic in Triggers

11. Avoid Returning JSON to Lightning Components

When we’re writing @AuraEnable methods for our Lightning Components, we frequently need to return more complex data structures, such as records, custom data types, or lists of these types.

An easy approach would be to serialize these objects into JSON, and then deserialize them within our component’s JavaScript (that is what the JS in JSON standards for after all!). image

However, this approach is actually an anti-pattern and can lead to some poor performance within our components. Instead, we should be directly returning these objects and letting the platform handle the rest for us. image

Converting our returned data into JSON results in us consuming large amounts of heap memory and spending many CPU cycles converting these objects into a lovely and long string


Question : Best practices follwed for triggeres.

Answer :

https://www.pantherschools.com/apex-trigger-best-practices-in-salesforce/

https://github.com/therishabh/salesforce-apex/blob/main/README.md#trigger

As a developer, to develop effective triggers we can follow the below best practices

  • One trigger per object
  • Logic Less Trigger
  • Context-specific handler methods
  • Avoid SOQL Query inside for loop
  • Avoid hardcoding IDs
  • Avoid nested for loop
  • Avoid DML inside for loop
  • Bulkify Your Code
  • Enforced Sharing in Salesforce
  • Use @future Appropriately
  • Use WHERE Clause in SOQL Query
  • Use Test-Driven Development

Question : How to connect two systems (Integartion related questions- Connected app,named credentials)

Answer :

https://github.com/therishabh/salesforce-apex/blob/main/README.md#integration-in-salesforce


Question : Different types of flows.

Answer :

Salesforce Flows can be classified into five subtypes:

Screen Flows
Require user interaction and include screens, local actions, steps, choices, or dynamic choices. For example, a customer survey after a support case is completed.

Schedule-Triggered Flows
Run in the background at a specified time and at a repeated frequency to perform actions on a batch of records. For example, a financial firm might need to generate reports at the end of every financial quarter.

Autolaunched Flows
Run without user interaction and don't support screens, local actions, choices, or choice sets. They are triggered by a specific event or record update and can automate complicated tasks like sending email notifications, modifying records, or creating new records. For example, when a large opportunity closes, send an alert to the right people on your team.

Record-Triggered Flows
Run in the background, either before or after a record save. They are triggered when a record is created or updated and can be used to automate processes such as updating related records or sending notifications to users. For example, when a large opportunity closes, send an alert to the right people on your team.

Platform Event-Triggered Flows
Run when a platform event message is received.


Question : What is the maximum number of records that can be processed by a trigger?

Answer :

A trigger can process a maximum of 200 records at a time.

However, if you're dealing with a larger number of records, Salesforce will automatically break down the process into chunks of 200. For example, if you have 1000 records to process, the trigger will be called 5 times, each time handling 200 records.

Additional Notes:
Platform Event triggers can handle up to 2000 records per chunk, which is different from standard object triggers.


Question : Context variables in triggers

Answer :

https://github.com/therishabh/salesforce-apex/blob/main/README.md#trigger-context-variables


Question : Future method and Quable methods (Limitation, which senario you will go for future menthod)

Answer :

https://github.com/therishabh/salesforce-apex/blob/main/README.md#asynchronous-processing-basics


Question : How to set field level security in Apex (WITH SECURITY_ENFORCED)?

Answer :

Setting field-level security in Apex ensures that your code respects the field-level security settings configured in Salesforce. Using the WITH SECURITY_ENFORCED keyword in SOQL queries is one way to enforce field-level security checks. Here's how you can use it:

Enforcing Field-Level Security with WITH SECURITY_ENFORCED
When you add WITH SECURITY_ENFORCED to your SOQL queries, Salesforce will automatically enforce field- and object-level security checks. If a user does not have access to a field or object, the query will fail, ensuring that your code does not inadvertently expose restricted data.

Example Usage
Here's an example of how to use WITH SECURITY_ENFORCED in a SOQL query:

try {
    List<Account> accounts = [SELECT Id, Name, Phone FROM Account WITH SECURITY_ENFORCED WHERE IsActive = true];
    // Process the accounts
    for (Account acc : accounts) {
        System.debug('Account Name: ' + acc.Name);
    }
} catch (Exception e) {
    System.debug('Insufficient permissions: ' + e.getMessage());
}

Question : Best Practices for flows (Avoid hard code values, mixed DMLs, Avoid DML statements inside Loop, Error handling etc).

Answer :

https://www.salesforceben.com/salesforce-flow-best-practices/

Here are the best Salesforce Flow practices I regularly follow when developing my flows.

  1. Always Test Your Flows
  2. Consider Using Subflows
  3. Never Perform DML Statements in Loops
  4. Document Your Flows
  5. Never Hard Code Ids (Use Constants if You Must)
  6. Plan for Faults (and Handle Them)
  7. Make Use of Schedule-Triggered Flow and Asynchronous Paths

Question : Mixed DML exception (Future method)

Answer :

https://github.com/therishabh/salesforce-apex/blob/main/README.md#future-method-in-apex

A mixed DML Operation Error comes when you try to perform DML operations on setup and non-setup objects in a single transaction.

Setup objects are the sObjects that affect the user’s access to records in the organization. Here are examples of the Setup Objects:

  1. ObjectPermissions
  2. PermissionSet
  3. PermissionSetAssignment
  4. QueueSObject
  5. Territory
  6. UserTerritory
  7. UserRole
  8. User

Question : Schedulable classes: can we do callouts directly from schedulable class or not.

Answer :

Salesforce does not allow us to make callouts from Schedulable classes

We used to get “System.CalloutException: Callout from scheduled Apex not supported” Error when we are making a web service callout from a class which is implementing Database.Schedulable interface because Salesforce does not allow us to make callouts from Schedulable classes.

@future method : A future runs as asynchronously. You can call a future method for executing long-running operations, such as callouts to external Web services or any operation you’d like to run in its own thread, on its own time

Scheduler Class

global class SampleScheduler implements Schedulable{
    
    global void execute(SchedulableContext sc) 
    {        
 
      BatchUtilClass.futureMethodSample();
    }    
}

Future Class Method
public class BatchUtilClass {
    @future(callout=true)
    public static void futureMethodSample() {
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://th-apex-http-callout.herokuapp.com/animals');
        request.setMethod('GET');
        HttpResponse response = http.send(request);

        if (response.getStatusCode() == 200) {
            Map<String, Object> results = (Map<String, Object>) JSON.deserializeUntyped(response.getBody());
            List<Object> animals = (List<Object>) results.get('animals');
            System.debug('Received the following animals:');
            for (Object animal: animals) {
                System.debug(animal);
            }
        }
    }
}

https://www.apexhours.com/system-calloutexception-callout-from-scheduled-apex-not-supported/


Question : Imaging you are processing a batch fo 50000 and you have to seprate the process sucessful and failed record, how you will achieve it.

Answer :

Processing large batches of records in Salesforce requires careful handling to ensure that successful and failed records are managed properly. Here’s how you can achieve this when processing a batch of 50,000 records using Batch Apex, with separate handling for successful and failed records:

Steps

  • Define Batch Apex Class: Implement the Database.Batchable interface.
  • Separate Successful and Failed Records: Use collections to keep track of successful and failed records during processing.
  • Handle Results in the Finish Method: Log or process the successful and failed records accordingly.

Example Batch Apex Class
Here’s a complete example demonstrating how to process 50,000 records, separating successful and failed records:

global class MyBatchClass implements Database.Batchable<SObject>, Database.Stateful {
    // Lists to keep track of successful and failed records
    private List<Account> successfulRecords = new List<Account>();
    private List<Account> failedRecords = new List<Account>();
    
    global Database.QueryLocator start(Database.BatchableContext BC) {
        // Query to fetch the records to be processed
        return Database.getQueryLocator('SELECT Id, Name FROM Account WHERE ...');
    }

    global void execute(Database.BatchableContext BC, List<Account> scope) {
        // Process each batch of records
        for (Account acc : scope) {
            try {
                // Perform some processing (e.g., update the name)
                acc.Name = acc.Name + ' - Processed';
                // Add to successful records list
                successfulRecords.add(acc);
            } catch (Exception e) {
                // Add to failed records list with an error message
                acc.addError('Processing failed: ' + e.getMessage());
                failedRecords.add(acc);
            }
        }
        
        // Perform DML operations
        if (!successfulRecords.isEmpty()) {
            try {
                update successfulRecords;
            } catch (Exception e) {
                // Handle exception if update fails for any record
                for (Account acc : successfulRecords) {
                    acc.addError('Update failed: ' + e.getMessage());
                    failedRecords.add(acc);
                }
            }
        }
    }

    global void finish(Database.BatchableContext BC) {
        // Log successful records
        for (Account acc : successfulRecords) {
            System.debug('Successfully processed account: ' + acc.Id);
        }
        
        // Log failed records
        for (Account acc : failedRecords) {
            System.debug('Failed to process account: ' + acc.Id + ' - Error: ' + acc.getErrors()[0].getMessage());
        }
        
        // Further handling of failed records (e.g., reprocess, notify admin)
    }
}

Explanation

  • Stateful Interface: The Database.Stateful interface is used to maintain the state across batch transactions, allowing you to keep track of successful and failed records.
  • Collections for Successful and Failed Records: Two lists (successfulRecords and failedRecords) are used to track records that are processed successfully and those that fail during processing.
  • Try-Catch Blocks: In the execute method, each record is processed within a try-catch block to handle exceptions individually and categorize the records accordingly.
  • Error Handling: Failed records are added to the failedRecords list with an appropriate error message.
  • Finish Method: In the finish method, both successful and failed records are logged. You can extend this part to send notifications, write to a custom object, or perform other actions as needed.

Question : Questions related to field level security.

Answer :

Field-Level Security (FLS) determines whether a user can view or edit the data in a specific field on an object. It is a key component of Salesforce’s security model and is applied to profiles and permission sets to control access to sensitive data.

https://github.com/therishabh/wipro-salesforce/blob/main/README.md#question--how-to-set-field-level-security-in-apex-with-security_enforced


Question : Database stateful and stateless (Difference and senario if you faced any)

Answer :

https://github.com/therishabh/salesforce-apex/blob/main/README.md#batch-apex

In Salesforce, Batch Apex classes can implement either the Database.Stateful or Database.Batchable interfaces. Understanding the difference between these two interfaces, as well as when and how to use them, is important for developing efficient and effective batch processes.

Difference Between Stateful and Stateless

  1. Database.Stateful:

    • Definition: Implements the Database.Stateful interface to maintain state across transaction boundaries.
    • Usage: Use Database.Stateful when you need to maintain state information (like aggregate values, collections, etc.) across multiple batch transactions.
    • Example: Tracking processed record IDs, maintaining counters, or aggregating values across all batches.
  2. Database.Batchable (Stateless):

    • Definition: Implements the Database.Batchable interface without the Database.Stateful interface, which means it is stateless.
    • Usage: Use Database.Batchable when you do not need to maintain state across batch transactions. Each batch transaction is independent and does not share any data with other transactions.
    • Example: Processing records independently where no shared state is required.

Example Scenario

Scenario: Aggregate Calculation Across Batches

Imagine you have a batch process that needs to calculate the total amount of all Opportunity records and update a custom field on the Account record with the aggregated value. Since this calculation requires maintaining a running total across multiple batches, you would use Database.Stateful.

Example Stateful Batch Apex Class

global class AggregateOpportunitiesBatch implements Database.Batchable<SObject>, Database.Stateful {
    private Decimal totalAmount = 0; // Maintain state

    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator('SELECT Amount, AccountId FROM Opportunity WHERE IsClosed = true');
    }

    global void execute(Database.BatchableContext BC, List<SObject> scope) {
        for (Opportunity opp : (List<Opportunity>) scope) {
            totalAmount += opp.Amount;
        }
    }

    global void finish(Database.BatchableContext BC) {
        // Update Accounts with the aggregated totalAmount
        List<Account> accountsToUpdate = [SELECT Id FROM Account WHERE Id IN (SELECT AccountId FROM Opportunity WHERE IsClosed = true)];
        for (Account acc : accountsToUpdate) {
            acc.Total_Opportunity_Amount__c = totalAmount;
        }
        update accountsToUpdate;
        System.debug('Total Opportunity Amount: ' + totalAmount);
    }
}

Example Stateless Batch Apex Class

For a stateless scenario, consider a batch process that updates a field on each Contact record independently, such as setting a Last_Processed__c date field to the current date.

global class UpdateContactsBatch implements Database.Batchable<SObject> {
    global Database.QueryLocator start(Database.BatchableContext BC) {
        return Database.getQueryLocator('SELECT Id FROM Contact');
    }

    global void execute(Database.BatchableContext BC, List<SObject> scope) {
        for (Contact con : (List<Contact>) scope) {
            con.Last_Processed__c = System.today();
        }
        update scope;
    }

    global void finish(Database.BatchableContext BC) {
        System.debug('Contact records updated with the current date.');
    }
}

Summary of Differences and Usage

Aspect Database.Stateful Database.Stateless
State Maintenance Maintains state across transactions Does not maintain state across transactions
Use Case Aggregations, counters, accumulating data Independent record processing
Example Aggregating Opportunity amounts Updating Contact fields independently

Scenarios Faced

Scenario 1: Aggregation and Counting

Situation: I needed to process a large number of records and keep a running count of how many records met certain criteria (e.g., number of closed Opportunities). This required using Database.Stateful to maintain the count across multiple batch transactions.

Implementation: Using a counter variable in a stateful batch class to maintain the running total and update a summary field on a parent record at the end.

Scenario 2: Independent Record Updates

Situation: I had to update a specific field on all Contact records in the system, and each update was independent of the others (e.g., setting a flag or date field).

Implementation: A stateless batch class was used because each Contact record was processed independently, and no shared state was required.

By understanding and applying the differences between Database.Stateful and Database.Batchable (stateless), you can choose the appropriate approach for your batch processing needs, ensuring efficient and effective execution of your Salesforce batch processes.


Question : How to pass the values from flow to Apex.

Answer :

https://github.com/therishabh/salesforce-apex/blob/main/README.md#invocable-method

Passing values from a Salesforce Flow to an Apex class involves creating an Apex invocable method that accepts input parameters. These parameters can then be mapped to Flow variables when the Flow is designed. Here is a step-by-step guide on how to achieve this:

Steps to Pass Values from Flow to Apex Class

  1. Create the Apex Class with an Invocable Method:

    • Define an Apex class.
    • Create an inner class to hold the input parameters.
    • Annotate the method with @InvocableMethod.
  2. Define Input Parameters in the Flow:

    • Use the Flow Builder to create variables.
    • Map these variables to the inputs of the invocable method.

Example

Let's say you want to pass a contact's first name, last name, and email from a Flow to an Apex class to create a new Contact record.

Step 1: Create the Apex Class

public class CreateContactFromFlow {
    
    // Define an inner class to hold the input parameters
    public class ContactInput {
        @InvocableVariable
        public String firstName;
        
        @InvocableVariable
        public String lastName;
        
        @InvocableVariable
        public String email;
    }
    
    // Define the invocable method
    @InvocableMethod(label='Create Contact' description='Create a new contact from Flow')
    public static void createContact(List<ContactInput> inputParams) {
        List<Contact> contactsToCreate = new List<Contact>();
        
        for (ContactInput input : inputParams) {
            Contact newContact = new Contact(
                FirstName = input.firstName,
                LastName = input.lastName,
                Email = input.email
            );
            contactsToCreate.add(newContact);
        }
        
        if (!contactsToCreate.isEmpty()) {
            insert contactsToCreate;
        }
    }
}

Step 2: Create the Flow and Map Variables

  1. Open Flow Builder: Go to Setup -> Process Automation -> Flows and click "New Flow".

  2. Select Screen Flow or Auto-launched Flow: Choose the type of Flow based on your requirements.

  3. Create Variables:

    • Create three variables: firstName, lastName, and email.
    • Ensure the data types match those expected by the Apex class (Text in this case).
  4. Add an Action:

    • In the Flow, add an "Action" element.
    • Search for the "Create Contact" action (the label you defined in the @InvocableMethod annotation).
    • Map the Flow variables to the input parameters of the invocable method.
  5. Finish the Flow:

    • Complete the Flow by adding any other necessary elements (e.g., screens, decisions, etc.).
    • Save and activate the Flow.

Detailed Steps in Flow Builder

  1. Create Variables:

    • Click "Manager" on the left panel.
    • Click "New Resource" and select "Variable".
    • Create firstName, lastName, and email variables with Text data type.
  2. Add Action Element:

    • Drag the "Action" element onto the canvas.
    • In the Action search box, type "Create Contact".
    • Select the "Create Contact" action.
  3. Map Flow Variables:

    • In the Action configuration, map the Flow variables to the inputs of the invocable method.
      • firstName -> firstName
      • lastName -> lastName
      • email -> email
  4. Complete the Flow:

    • Add any other elements as needed.
    • Connect the elements to define the Flow logic.
    • Save and activate the Flow.

Example Flow Configuration

Here's how the Action configuration might look:

  • Label: Create Contact
  • API Name: Create_Contact
  • Set Input Values:
    • firstName: {!firstName}
    • lastName: {!lastName}
    • email: {!email}

Conclusion

By following these steps, you can effectively pass values from a Flow to an Apex class in Salesforce. This approach leverages the power of Flow for user-friendly configuration and the flexibility of Apex for complex business logic.


Question : Field restriction by apex

Answer :

https://github.com/therishabh/salesforce-apex/blob/main/README.md#user-mode-vs-system-mode

In Salesforce, Field-Level Security (FLS) is an essential component of data security, ensuring that users can only view or edit fields they have permission to access. While Field-Level Security is primarily managed through profiles and permission sets, you might need to handle field restrictions programmatically in Apex to respect these settings or implement additional security measures.

How to Handle Field Restrictions in Apex

1. Check Field-Level Security Programmatically

Before performing operations on a field, you should check if the current user has access to that field. Salesforce provides methods in the Schema class to check field accessibility.

Example: Checking Field Accessibility

// Example to check if the current user has access to a field
public class FieldSecurityUtil {
    public static Boolean isFieldAccessible(Schema.SObjectField field) {
        Schema.DescribeFieldResult fieldDescribe = field.getDescribe();
        return fieldDescribe.isAccessible();
    }
    
    public static Boolean isFieldEditable(Schema.SObjectField field) {
        Schema.DescribeFieldResult fieldDescribe = field.getDescribe();
        return fieldDescribe.isUpdateable();
    }
}

Usage in Apex Code

if (FieldSecurityUtil.isFieldAccessible(Account.MyField__c)) {
    // Proceed with logic for accessible field
    Account acc = [SELECT Id, MyField__c FROM Account LIMIT 1];
    System.debug('Field value: ' + acc.MyField__c);
} else {
    System.debug('Field is not accessible.');
}

2. Handle Field-Level Security in Triggers

When writing triggers, ensure that your code respects field-level permissions. For example, if your trigger updates fields, check if the fields are editable.

Example: Trigger Code

trigger AccountTrigger on Account (before update) {
    for (Account acc : Trigger.new) {
        if (FieldSecurityUtil.isFieldEditable(Account.MyField__c)) {
            // Logic to update the field if it is editable
            acc.MyField__c = 'New Value';
        } else {
            // Logic for fields that are not editable
            System.debug('Field MyField__c is not editable.');
        }
    }
}

Question : application event in LWC

Answer :

Events are used in LWC for components communication. There are typically 3 approaches for communication between the components using events.

  1. Parent to Child Event communication in Lightning web component
  2. Child to Parent Event Communication in Lightning Web Component
  3. Publish Subscriber model (PubSub model) in Lightning Web Component or LMS (Two components which doesn’t have a direct relation)

image

https://github.com/therishabh/salesforce-lwc?tab=readme-ov-file#parent-to-child-communication


Question : life cycle of LWC

Answer :

https://github.com/therishabh/salesforce-lwc?tab=readme-ov-file#lifecycle-hooks


Question : Named credential

Answer :

In Salesforce, a Named Credential is a configuration that allows you to securely store authentication details for external services. This feature is particularly useful for integrating with external systems or APIs, as it simplifies the management of authentication and improves security by keeping sensitive information out of the codebase.

Using Named Credentials in Apex

You can use Named Credentials in Apex code to make HTTP requests without hardcoding credentials. Salesforce handles authentication automatically based on the Named Credential configuration.

Example: Making an HTTP Request

public class MyHttpClient {
    public void callExternalService() {
        HttpRequest req = new HttpRequest();
        req.setEndpoint('callout:My_Named_Credential/some/resource');
        req.setMethod('GET');
        
        Http http = new Http();
        HttpResponse res = http.send(req);
        
        if (res.getStatusCode() == 200) {
            // Process response
            System.debug(res.getBody());
        } else {
            // Handle error
            System.debug('Error: ' + res.getStatusCode() + ' ' + res.getStatus());
        }
    }
}

In this example, callout:My_Named_Credential refers to the Named Credential you configured, and Salesforce automatically handles the authentication.

Named Credentials in Salesforce are a powerful feature for securely managing authentication details when integrating with external services. They simplify the process of making secure HTTP requests and managing credentials, enhancing both security and maintainability of your integration solutions.


Question : Open Id connect for integration

Answer :


Question : Calling one batch to another batch

Answer :

https://www.emizentech.com/blog/call-batch-apex-from-another-batch-apex.html

https://github.com/therishabh/salesforce-apex/blob/main/README.md#batch-apex


Question : Is there a way to callout triggers

Answer :

In Salesforce, "callout triggers" typically refers to making HTTP callouts from triggers, but it’s important to note that Salesforce does not support direct HTTP callouts from triggers due to governor limits and best practices.

Here’s how you can indirectly achieve callouts from triggers using asynchronous methods:

Indirect Callouts from Triggers

1. Using Queueable Apex

Queueable Apex allows you to perform asynchronous operations, including HTTP callouts. You can call a Queueable Apex class from a trigger to handle the callout.

Steps to Use Queueable Apex for Callouts

  1. Create the Queueable Apex Class

    This class will perform the HTTP callout.

    public class CalloutQueueable implements Queueable, Database.AllowsCallouts {
        public void execute(QueueableContext context) {
            HttpRequest req = new HttpRequest();
            req.setEndpoint('https://api.example.com/resource');
            req.setMethod('GET');
            req.setHeader('Content-Type', 'application/json');
            
            Http http = new Http();
            HttpResponse res = http.send(req);
            
            if (res.getStatusCode() == 200) {
                // Process response
                System.debug(res.getBody());
            } else {
                // Handle error
                System.debug('Error: ' + res.getStatusCode() + ' ' + res.getStatus());
            }
        }
    }
  2. Call the Queueable Apex Class from the Trigger

    In your trigger, you can enqueue the Queueable job.

    trigger AccountTrigger on Account (after insert) {
        if (Trigger.isAfter && Trigger.isInsert) {
            // Call Queueable Apex to perform callout
            System.enqueueJob(new CalloutQueueable());
        }
    }

2. Using Future Methods

Future methods also allow asynchronous processing but are less flexible than Queueable Apex. They can be used for simple asynchronous operations and are limited in their ability to chain or handle complex scenarios.

Steps to Use Future Methods for Callouts

  1. Create a Future Method

    Define a method in a class marked with @future to perform the callout.

    public class CalloutFuture {
        @future(callout=true)
        public static void makeCallout() {
            HttpRequest req = new HttpRequest();
            req.setEndpoint('https://api.example.com/resource');
            req.setMethod('GET');
            req.setHeader('Content-Type', 'application/json');
            
            Http http = new Http();
            HttpResponse res = http.send(req);
            
            if (res.getStatusCode() == 200) {
                // Process response
                System.debug(res.getBody());
            } else {
                // Handle error
                System.debug('Error: ' + res.getStatusCode() + ' ' + res.getStatus());
            }
        }
    }
  2. Call the Future Method from the Trigger

    Invoke the future method from your trigger.

    trigger AccountTrigger on Account (after insert) {
        if (Trigger.isAfter && Trigger.isInsert) {
            // Call Future Method to perform callout
            CalloutFuture.makeCallout();
        }
    }

Question : About recursive triggers

Answer :

https://github.com/therishabh/salesforce-apex/blob/main/README.md#how-to-avoid-recursion-in-trigger


Question : Reason for bulkification of your code

Answer :

Bulkification in Salesforce refers to the practice of designing Apex code to handle multiple records efficiently in a single execution context.

Reasons for Bulkification

  1. Governor Limits Compliance

    Salesforce enforces various governor limits, such as limits on the number of SOQL queries, DML operations, and CPU time. Non-bulkified code can easily exceed these limits if it processes records individually. Bulkified code ensures that operations are performed in bulk, minimizing the number of SOQL queries and DML statements, and helps avoid hitting these limits.

  2. Performance Optimization

    Processing records in bulk reduces the number of database operations and HTTP requests, which improves performance.

  3. Avoiding Recursive Triggers

    Bulkified code reduces the likelihood of hitting recursive triggers.

  4. Scalability

    Bulkification ensures that code can handle large volumes of data without performance degradation. For example, if you need to process 10,000 records, bulkified code can handle this efficiently by processing records in batches rather than one at a time.

  5. Maintaining Data Integrity

    Bulk operations help maintain data integrity by ensuring that related records are processed together. For instance, when updating a set of records, bulk operations ensure that related updates are performed consistently, reducing the risk of partial updates or data inconsistencies.

Key Practices for Bulkification

  1. Use Collections

    Always use collections (such as Lists, Maps, and Sets) to handle multiple records. This allows you to perform operations in bulk.

    // Bulk Insert Example
    List<Account> accountsToInsert = new List<Account>();
    for (Integer i = 0; i < 200; i++) {
        accountsToInsert.add(new Account(Name = 'Account ' + i));
    }
    insert accountsToInsert;
  2. Limit SOQL Queries

    Avoid performing SOQL queries inside loops. Instead, query all needed records in a single query and use a Map to access them by ID.

    // Bulk Query Example
    List<Account> accounts = [SELECT Id, Name FROM Account WHERE CreatedDate = LAST_N_DAYS:30];
    Map<Id, Account> accountMap = new Map<Id, Account>();
    for (Account acc : accounts) {
        accountMap.put(acc.Id, acc);
    }
    
    // Access accounts by ID from the map
  3. Bulkify Triggers

    Ensure that triggers are designed to handle multiple records at once. Use collections to process records and avoid SOQL or DML operations inside loops.

    trigger AccountTrigger on Account (before insert, before update) {
        Set<Id> accountIds = new Set<Id>();
        for (Account acc : Trigger.new) {
            accountIds.add(acc.Id);
        }
    
        // Perform bulk operations
        List<Contact> contacts = [SELECT Id, AccountId FROM Contact WHERE AccountId IN :accountIds];
        // Process contacts
    }
  4. Use Batch Apex for Large Data Volumes

    When dealing with very large datasets, use Batch Apex to process records in manageable chunks.

    global class MyBatchClass implements Database.Batchable<sObject> {
        global Database.QueryLocator start(Database.BatchableContext BC) {
            return Database.getQueryLocator('SELECT Id FROM Account');
        }
    
        global void execute(Database.BatchableContext BC, List<sObject> scope) {
            // Bulk processing logic
            List<Account> accountsToUpdate = new List<Account>();
            for (Account acc : (List<Account>)scope) {
                acc.Name = 'Updated Name';
                accountsToUpdate.add(acc);
            }
            update accountsToUpdate;
        }
    
        global void finish(Database.BatchableContext BC) {
            // Post-processing logic
        }
    }

Question : Database operation and syntax

Answer :

1. SOQL (Salesforce Object Query Language)

SOQL is used to query Salesforce data. It’s similar to SQL (Structured Query Language) but is tailored for the Salesforce data model.

Basic Syntax

SELECT field1, field2 FROM ObjectName WHERE condition

Examples

  1. Query Records

    // Query to select all Account records with a specific name
    List<Account> accounts = [SELECT Id, Name FROM Account WHERE Name = 'Acme Corp'];
  2. Query with Multiple Conditions

    // Query to select contacts with a specific last name and account
    List<Contact> contacts = [SELECT Id, FirstName, LastName FROM Contact WHERE LastName = 'Smith' AND Account.Name = 'Acme Corp'];
  3. Query with Relationships

    // Query to select accounts and related contacts
    List<Account> accountsWithContacts = [SELECT Id, Name, (SELECT Id, FirstName, LastName FROM Contacts) FROM Account];

2. SOSL (Salesforce Object Search Language)

SOSL is used for text searches across multiple objects and fields.

Basic Syntax

FIND {searchQuery} IN {RETURNING object1(field1, field2), object2(field1, field2)}

Examples

  1. Search Across Objects

    // Search for 'Acme' across Account and Contact objects
    List<List<SObject>> searchResults = [FIND 'Acme' IN ALL FIELDS RETURNING Account(Id, Name), Contact(Id, FirstName, LastName)];
  2. Search with Specific Fields

    // Search for 'Smith' in the LastName field of Contact
    List<Contact> contacts = [FIND 'Smith' IN NAME RETURNING Contact(Id, FirstName, LastName)];

3. DML Operations

DML operations are used to manipulate data, including inserting, updating, deleting, and undeleting records.

Syntax

// Insert
insert newObject;

// Update
update existingObject;

// Delete
delete existingObject;

// Undelete
undelete existingObject;

Examples

  1. Insert Records

    // Create a new account and insert it
    Account newAccount = new Account(Name = 'Acme Corp');
    insert newAccount;
  2. Update Records

    // Update an existing account
    Account existingAccount = [SELECT Id, Name FROM Account WHERE Name = 'Acme Corp' LIMIT 1];
    existingAccount.Name = 'Acme Corporation';
    update existingAccount;
  3. Delete Records

    // Delete an existing account
    Account accountToDelete = [SELECT Id FROM Account WHERE Name = 'Acme Corporation' LIMIT 1];
    delete accountToDelete;
  4. Undelete Records

    // Undelete a record from the Recycle Bin
    Account accountToUndelete = [SELECT Id FROM Account WHERE Name = 'Acme Corporation' LIMIT 1 ALL ROWS];
    undelete accountToUndelete;

Question : What are public component in LWC

Answer :


Question : Types of decorators in LWC

Answer :

There are three type of Decorators in Lightning web components.

  • Api
  • Track
  • Wire

https://www.apexhours.com/decorators-in-lightning-web-component/


Question : Difference between, trigger.old and Trigger.oldmap

Answer :

Trigger.old: Returns a list of the old versions of the sObject records. Trigger.old should return a type ofList<sObject__c>.Note that this sObject list is only available in the update and delete triggers.

Trigger.oldMap: A map of IDs to the old versions of the sObject records. Trigger.oldMap should return a type of Map<Id, sObject__c>.Note that this map is only available in the update and delete triggers.


Question : Not using @future annotation in webservices callout, what will happen

Answer :

Without the annotation, the Web service callout is made from the same thread that is executing the Apex code, and no additional processing can occur until the callout is complete

In Salesforce, the @future annotation is used to execute methods asynchronously. This can be useful for operations that need to run in the background and do not require immediate results, such as making callouts to external web services. However, if you do not use the @future annotation for web service callouts and instead make a synchronous callout from within the same execution context, there are several considerations and potential issues:

Key Points and Consequences of Not Using @future for Web Service Callouts

Question : How can you implement recursive trigger in salesforce

Answer :

https://github.com/therishabh/salesforce-apex/blob/main/README.md#how-to-avoid-recursion-in-trigger


Question : Composite request

Answer :

A Composite Request enables you to bundle multiple REST API requests into a single HTTP call. This is helpful for operations that involve creating, updating, or querying multiple records simultaneously. It helps to:

  • Reduce API Call Counts: Minimize the number of API calls by sending a single composite request instead of multiple individual requests.
  • Improve Efficiency: Decrease network latency and improve performance by batching operations.
  • Handle Complex Transactions: Perform complex transactions and maintain data consistency by processing multiple related operations together.

Why Composite Resources

Lets understand the advantage of composite API.

  • Multiple REST API calls for single call
  • Processing speed can be made faster by collating the subrequests.
  • Improves the performance of the application
  • No additional coding required at Salesforce.
  • Single call toward API limits.
  • Synchronous responses.
  • Multiple ways in composite resources work.
  • Upsert upto five levels deep relationships.
  • Flexible on upserting related or non related records.
  • Can do a GET subrequest and the result can be input to next POST subrequest.
  • Can handle more complicated and related objects and data.

Sample Request and URL.

URL : /services/data/vXX.X/composite

Request Body sample.

{
"compositeRequest" : [
  {
  "method" : "POST",
  "url" : "/services/data/v52.0/sobjects/Account",
  "referenceId" : "refAccount",
  "body" : { "Name" : "APEX HOURS" }
  },
  {
  "method" : "POST",
  "url" : "/services/data/v52.0/sobjects/Contact",
  "referenceId" : "refContact",
  "body" : { 
    "LastName" : "AMIT CHAUDHARY",
    "AccountId" : "@{refAccount.id}"
    }
  }]
}

Question : Component event and application event difference

Answer :

Component Events in LWC

Component Events in LWC are used for communication between components that have a parent-child relationship. These events are specifically designed to facilitate interaction within a component hierarchy.

Example

Child Component (childComponent.html)

<template>
    <lightning-button label="Click Me" onclick={handleClick}></lightning-button>
</template>

Child Component (childComponent.js)

import { LightningElement } from 'lwc';

export default class ChildComponent extends LightningElement {
    handleClick() {
        // Create and dispatch a custom event
        const event = new CustomEvent('myevent', {
            detail: { message: 'Hello from child' }
        });
        this.dispatchEvent(event);
    }
}

Parent Component (parentComponent.html)

<template>
    <c-child-component onmyevent={handleChildEvent}></c-child-component>
</template>

Parent Component (parentComponent.js)

import { LightningElement } from 'lwc';

export default class ParentComponent extends LightningElement {
    handleChildEvent(event) {
        // Handle the event from the child component
        const message = event.detail.message;
        console.log(message); // Outputs: Hello from child
    }
}

Application Events in LWC

Application Events in LWC are not a part of the framework like in Aura components. LWC uses a different approach for global communication. Instead of application events, LWC relies on other methods such as:

  1. Pub/Sub (Publish/Subscribe) Model: For cross-component communication that is not tied to a parent-child relationship. This pattern is typically managed using a custom event bus or a pub/sub library.

  2. Lightning Message Service (LMS): For inter-component communication within the Lightning Experience and Salesforce mobile app. LMS enables message passing across different components, even if they are not in a direct parent-child relationship.

https://github.com/therishabh/salesforce-lwc?tab=readme-ov-file#component-communication


Question : What is LDS(Lightning Data Services) in lwc

Answer :

https://medium.com/@saurabh.samirs/lightning-data-services-lds-in-lwc-67e9a50039d5

Lightning Data Service (LDS) is a powerful tool provided by Salesforce that allows Lightning Web Components (LWC) to interact with Salesforce data without the need for Apex code. It operates on the client-side and offers several key features that streamline data retrieval and management within LWC.

One of the key benefits of LDS is its client-side caching mechanism. When a component fetches data using LDS, the data is cached locally in the browser’s memory. Subsequent requests for the same data within the same session can be served from the cache, eliminating the need for additional server round trips. This improves performance and responsiveness of the application, especially in scenarios where the same data is accessed frequently.

Benefits Over Traditional Apex Data Queries:
Compared to traditional Apex data queries, LDS offers several advantages:

Reduced Server Load: Since data is fetched and cached on the client side, LDS reduces the load on the Salesforce server by minimizing the number of server requests.

Faster Response Times: With client-side caching, LDS can serve data more quickly, leading to faster response times and improved user experience.

Enhanced Offline Support: LDS supports offline data access, allowing components to continue functioning even when the user is offline or experiencing connectivity issues.

Automatic Record Updates: LDS automatically detects changes to records and updates the local cache accordingly, ensuring that components always have access to the latest data without manual refreshing.

Example:
Let’s consider an example where we have a Lightning Web Component that displays a list of accounts using LDS.

<!-- accountsList.html -->
<template>
    <lightning-card title="Accounts List">
        <template if:true={accounts}>
            <ul>
                <template for:each={accounts} for:item="account">
                    <li key={account.Id}>{account.Name}</li>
                </template>
            </ul>
        </template>
        <template if:false={accounts}>
            No accounts found.
        </template>
    </lightning-card>
</template>
// accountsList.js
import { LightningElement, wire } from 'lwc';
import { getListUi } from 'lightning/uiListApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
 
export default class AccountsList extends LightningElement {
    @wire(getListUi, { objectApiName: ACCOUNT_OBJECT, listViewApiName: 'All' })
    wiredAccounts({ error, data }) {
        if (data) {
            this.accounts = data.records.records;
        } else if (error) {
            console.error(error);
        }
    }
}

Output:
image

In this example, we use the getListUi wire adapter from lightning/uiListApi to fetch a list of accounts. The result is automatically cached by LDS, and subsequent requests for the same data will be served from the cache, resulting in improved performance and responsiveness.

The base component of Lightning Data Service are

lightning-record-edit-form — Displays an editable form.
lightning-record-view-form — Displays a read-only form.
lightning-record-form — Supports edit, view, and read-only modes.


Question : SOQL 101 Exception

Answer :

In Salesforce we got the System.limitException: Too many SOQL Queries 101 very often.

In Salesforce we can encounter the Salesforce Governor Limits system limit exception too many soql queries 101 very often. This means we can only have up to 100 SOQL in a single context. This is a hard limit, which means you can’t increase it by contacting Salesforce support.

The following error appears when we exceed the Governors Limit.

System.LimitException: Too many SOQL queries: 101 error

As per the governor limit, the Total number of SOQL queries issued is 100 in Synchronous and 200 in Asynchronous context.

Let see the all other reason for SOQL 101 Error.

  • Soql inside the for Loop
  • A Trigger is not bulkified.
  • Trigger is recursive
  • Multiple processes are executing at the same time and updating the same record in the same transection.

Let see how to resolve this System.LimitException: Too many SOQL queries: 101 error.

  • Avoid SOQL queries inside For Loop
  • Bulkify Apex Trigger and Recursion Handling
  • Move some business logic into @future
  • Minimize the No.of SOQLs by merging the queries

Question : How will you get the data from Apex to LWC

Answer :

To get data from Apex to Lightning Web Components (LWC), you generally use the @wire decorator or imperative Apex calls. Here’s a brief overview of each method:

1. Using @wire Decorator

The @wire decorator is used for reactive data binding. It automatically handles data retrieval and refreshes the component when the data changes.

Steps:

  1. Create an Apex Method

    Define an Apex method in a class with @AuraEnabled annotation. Ensure the method is public and static.

    public with sharing class AccountController {
        @AuraEnabled(cacheable=true)
        public static List<Account> getAccounts() {
            return [SELECT Id, Name FROM Account LIMIT 10];
        }
    }
  2. Use @wire in LWC

    Import the Apex method and use the @wire decorator to call it in your LWC.

    HTML (myComponent.html):

    <template>
        <template if:true={accounts.data}>
            <ul>
                <template for:each={accounts.data} for:item="account">
                    <li key={account.Id}>{account.Name}</li>
                </template>
            </ul>
        </template>
        <template if:true={accounts.error}>
            <p>Error: {accounts.error.message}</p>
        </template>
    </template>

    JavaScript (myComponent.js):

    import { LightningElement, wire } from 'lwc';
    import getAccounts from '@salesforce/apex/AccountController.getAccounts';
    
    export default class MyComponent extends LightningElement {
        @wire(getAccounts) accounts;
    }

    Here, accounts.data contains the retrieved data, and accounts.error will handle any errors.

2. Using Imperative Apex Calls

Imperative Apex calls are used when you need more control over when and how data is fetched. This method is useful for scenarios where the data retrieval is not reactive or is based on user actions.

Steps:

  1. Create an Apex Method

    Same as above, define an Apex method with @AuraEnabled.

  2. Call Apex Imperatively in LWC

    HTML (myComponent.html):

    <template>
        <lightning-button label="Get Accounts" onclick={handleGetAccounts}></lightning-button>
        <template if:true={accounts}>
            <ul>
                <template for:each={accounts} for:item="account">
                    <li key={account.Id}>{account.Name}</li>
                </template>
            </ul>
        </template>
        <template if:true={error}>
            <p>Error: {error.message}</p>
        </template>
    </template>

    JavaScript (myComponent.js):

    import { LightningElement, track } from 'lwc';
    import getAccounts from '@salesforce/apex/AccountController.getAccounts';
    
    export default class MyComponent extends LightningElement {
        @track accounts;
        @track error;
    
        handleGetAccounts() {
            getAccounts()
                .then(result => {
                    this.accounts = result;
                    this.error = undefined;
                })
                .catch(error => {
                    this.error = error;
                    this.accounts = undefined;
                });
        }
    }

    In this example, handleGetAccounts is called when a button is clicked, fetching the data imperatively and updating the component state.

Summary

  • @wire Decorator: Use for reactive data binding. Automatically fetches and updates data when the data source changes.
  • Imperative Apex Calls: Use for more control over data fetching, typically in response to user actions or specific events.

Both methods are effective for retrieving data from Apex to LWC, and the choice between them depends on the specific requirements of your component.


Question : What is Wire method

Answer :

https://github.com/therishabh/salesforce-lwc?tab=readme-ov-file#wire-service


Question : Concept of promises in LWC ?

Answer :

In Lightning Web Components (LWC), Promises are a fundamental part of asynchronous programming and are used to handle operations that may take some time to complete, such as fetching data from a server, performing API calls, or executing other asynchronous tasks. Promises are a native JavaScript feature, and they are used extensively in LWC for handling asynchronous operations.

What is a Promise?

A Promise is an object representing the eventual completion or failure of an asynchronous operation and its resulting value. Promises provide a way to write asynchronous code that is easier to read and maintain compared to traditional callback-based approaches.

A Promise has three states:

  1. Pending: The initial state, where the promise has not yet been resolved or rejected.
  2. Fulfilled: The state when the asynchronous operation is completed successfully.
  3. Rejected: The state when the asynchronous operation fails.

Creating and Using Promises

In JavaScript, you create a Promise by using the Promise constructor, which takes a function with two arguments: resolve and reject. The resolve function is called when the operation completes successfully, while the reject function is called when the operation fails.

Example

Here's a basic example of creating and using a Promise:

// Create a Promise
const myPromise = new Promise((resolve, reject) => {
    // Asynchronous operation
    setTimeout(() => {
        const success = true; // This would be your condition
        if (success) {
            resolve('Operation successful!');
        } else {
            reject('Operation failed!');
        }
    }, 1000); // Simulate async operation with 1 second delay
});

// Use the Promise
myPromise
    .then(result => {
        console.log(result); // Outputs: 'Operation successful!'
    })
    .catch(error => {
        console.error(error); // Outputs: 'Operation failed!'
    });

Promises in LWC

In LWC, Promises are commonly used for handling asynchronous operations such as:

  1. Making Apex Calls: When calling Apex methods from JavaScript, the returned Promise allows you to handle the success or failure of the call.
  2. Fetching Data: Using fetch API or other asynchronous operations where Promises are used to handle the response.

Example of Using Promises with Apex

Apex Method (MyApexClass.apxc)

public with sharing class MyApexClass {
    @AuraEnabled(cacheable=true)
    public static String getServerData() {
        return 'Data from the server';
    }
}

LWC JavaScript (myComponent.js)

import { LightningElement, wire } from 'lwc';
import getServerData from '@salesforce/apex/MyApexClass.getServerData';

export default class MyComponent extends LightningElement {
    serverData;

    connectedCallback() {
        this.fetchData();
    }

    fetchData() {
        getServerData()
            .then(result => {
                this.serverData = result;
                console.log('Data received:', result);
            })
            .catch(error => {
                console.error('Error:', error);
            });
    }
}

Chaining Promises

Promises can be chained to perform multiple asynchronous operations sequentially. Each then returns a new Promise, allowing you to chain multiple operations.

Example

fetchData()
    .then(result => {
        return processResult(result); // Returns a new Promise
    })
    .then(processedData => {
        return saveData(processedData); // Returns a new Promise
    })
    .then(finalResult => {
        console.log('Final result:', finalResult);
    })
    .catch(error => {
        console.error('Error:', error);
    });

Error Handling

catch method is used to handle errors that occur during the execution of the Promise chain. It catches any errors that occur in the then methods prior to it.

Example

fetchData()
    .then(result => {
        // Process the result
        return processResult(result);
    })
    .catch(error => {
        // Handle errors that occurred in fetchData or processResult
        console.error('Error:', error);
    });

Using async and await with Promises

The async and await syntax provides a more concise way to work with Promises and is often preferred for readability. async functions return a Promise, and await is used to pause execution until the Promise is resolved or rejected.

Example

async function fetchData() {
    try {
        const result = await getServerData();
        console.log('Data received:', result);
    } catch (error) {
        console.error('Error:', error);
    }
}

Using async in LWC

import { LightningElement } from 'lwc';
import getServerData from '@salesforce/apex/MyApexClass.getServerData';

export default class MyComponent extends LightningElement {
    serverData;

    async connectedCallback() {
        try {
            this.serverData = await getServerData();
            console.log('Data received:', this.serverData);
        } catch (error) {
            console.error('Error:', error);
        }
    }
}

Summary

  • Promises represent asynchronous operations and are used to handle the eventual completion (or failure) of these operations.
  • In LWC, Promises are used for handling asynchronous operations like Apex calls or data fetching.
  • Chaining Promises allows for sequential asynchronous operations, while error handling is done using catch.
  • async and await provide a more readable way to work with Promises, simplifying asynchronous code.

By leveraging Promises effectively, you can manage asynchronous operations in your LWC applications more efficiently, improving code readability and maintainability.


Question : diff between userflow and web server flow ( connected App authorization)?

Answer :


Question : Platform event?

Answer :

https://github.com/therishabh/salesforce-apex/blob/main/README.md#platform-event


Question : Managed Package- exp

Answer :


Question : styling hooks in LWC?

Answer :

In Lightning Web Components (LWC), styling is managed using CSS. The framework provides several methods to style your components, including the use of CSS custom properties, shadow DOM styling, and global styles. While there isn't a direct concept called "styling hooks" like in some other frameworks, you can leverage various techniques to effectively style your components.

1. Component-Level Styling

Each LWC component has its own scoped CSS file. Styles defined in a component’s CSS file only apply to that component, thanks to Shadow DOM encapsulation.

Example

HTML (myComponent.html):

<template>
    <div class="my-class">Styled Text</div>
</template>

CSS (myComponent.css):

.my-class {
    color: blue;
    font-size: 16px;
}

2. CSS Custom Properties (Variables)

You can use CSS custom properties to define variables that can be used across components. These can be defined in a global CSS file and used in component CSS files.

Example

Global CSS (styles.css):

:root {
    --primary-color: #3498db;
}

.my-class {
    color: var(--primary-color);
}

Component CSS (myComponent.css):

.my-class {
    background-color: var(--primary-color);
}

3. Scoped CSS Variables

Scoped CSS variables are defined within a component and can be used within that component’s stylesheet.

Example

Component CSS (myComponent.css):

:host {
    --component-background: #f0f0f0;
}

.my-class {
    background-color: var(--component-background);
}

4. Global Styles

Global styles are applied to the entire Lightning Experience. You can use them to define shared styles across multiple components. This is typically done in a styles.css file in your Salesforce org or using static resources.

Example

Static Resource (globalStyles.css):

.my-global-class {
    font-family: Arial, sans-serif;
}

Using Global Styles in Component:

<template>
    <div class="my-global-class">Global Styled Text</div>
</template>

5. Dynamic Styling

For dynamic styling, you can use JavaScript to add or remove CSS classes based on conditions.

Example

HTML (myComponent.html):

<template>
    <div class={dynamicClass}>Dynamic Styled Text</div>
</template>

JavaScript (myComponent.js):

import { LightningElement, api } from 'lwc';

export default class MyComponent extends LightningElement {
    @api isHighlighted = false;

    get dynamicClass() {
        return this.isHighlighted ? 'highlight' : 'normal';
    }
}

CSS (myComponent.css):

.highlight {
    background-color: yellow;
}

.normal {
    background-color: white;
}

6. Styling Within Shadow DOM

LWC uses Shadow DOM to encapsulate component styles, meaning styles do not bleed through to or from other components. However, you can still apply styles within the component’s shadow DOM.

Example

Component CSS (myComponent.css):

:host {
    display: block;
    padding: 10px;
}

h1 {
    color: green;
}

Summary

While LWC doesn't have specific "styling hooks," you can style components effectively using:

  • Component-Level Styling: Scoped CSS files.
  • CSS Custom Properties: For reusable variables.
  • Scoped CSS Variables: Within components.
  • Global Styles: For consistent styling across components.
  • Dynamic Styling: Using JavaScript for condition-based styles.
  • Shadow DOM: Encapsulation ensures styles are contained within the component.

These techniques allow you to create well-styled, maintainable Lightning Web Components.


Question : have you worked in service console.

Answer : Yes


Question : How did you do deployment

Answer :

https://github.com/therishabh/salesforce-apex/blob/main/README.md#deployment


Question : Involved in any deployment

Answer :

https://github.com/therishabh/salesforce-apex/blob/main/README.md#deployment


Question : Can we use multiple decorators for one property

Answer :

In Lightning Web Components (LWC), you can use multiple decorators on a single property, but there are specific rules and scenarios where this is appropriate. The most common decorators in LWC are @api, @track, and @wire.

Here's a breakdown of each decorator and their usage:

1. @api Decorator

  • Purpose: Marks a property or method as public, making it accessible to other components.

2. @track Decorator

  • Purpose: Makes a property reactive, meaning changes to the property will trigger a re-render of the component.

3. @wire Decorator

  • Purpose: Connects a property or method to a Salesforce data source or an imperative Apex call.

Using Multiple Decorators

You can use multiple decorators on a single property if it makes sense for the specific use case. However, they are generally used in distinct contexts, and applying them simultaneously requires understanding their combined effects.

Example Scenarios

  1. @api and @track

    If you want a property to be both exposed to parent components and reactive within the component, you can combine @api and @track.

    import { LightningElement, api, track } from 'lwc';
    
    export default class MyComponent extends LightningElement {
        @api @track myProperty = 'Initial Value';
    
        handleChange(event) {
            this.myProperty = event.target.value; // This change will be tracked and exposed to parent components
        }
    }

    In this example, myProperty is exposed to parent components and will trigger re-renders when its value changes.

  2. @api and @wire

    You typically don't use @wire with @api on the same property because @wire is generally used for retrieving data and @api is for public properties. Instead, @wire is often used with a method or a private property.

    import { LightningElement, api, wire } from 'lwc';
    import getAccount from '@salesforce/apex/AccountController.getAccount';
    
    export default class MyComponent extends LightningElement {
        @api accountId;
    
        @wire(getAccount, { id: '$accountId' })
        account;
    
        // The account property is automatically updated with data from the wire service
    }

    Here, @api exposes accountId to parent components, and @wire retrieves account data based on accountId.

Summary

  • @api: Makes properties and methods public.
  • @track: Makes properties reactive within the component.
  • @wire: Connects properties or methods to Salesforce data sources.

You can use @api and @track together if you need a property to be public and reactive. However, combining @api with @wire directly on the same property is uncommon and typically not required because @wire handles data binding and reactivity on its own.


Question : what is the need of LWC, when we are already having Aura

Answer :

Lightning Web Components (LWC) is preferred over Aura for the following reasons:

  1. Modern Standards: LWC uses modern web standards (like Web Components and ES6+), making it more efficient and familiar to web developers.
  2. Performance: LWC has better performance due to its lightweight nature and efficient rendering.
  3. Simplified Development: LWC offers a simpler development model with standard HTML, CSS, and JavaScript.
  4. Encapsulation: LWC uses Shadow DOM for better style and script encapsulation.
  5. Reactivity: LWC provides a reactive data-binding model for easier state management.
  6. Tooling: LWC integrates well with modern development tools and practices.

Aura is still used for existing components and applications but LWC is encouraged for new development due to its advantages.


Question : How will you overcome the governor limit

Answer :

To overcome Salesforce governor limits:

  • Use Batch Apex, Queueable Apex, Future Methods, and Scheduled Apex for asynchronous processing.
  • Optimize use of collections and avoid SOQL and DML in loops.
  • Efficiently query data and use the Limits class to monitor governor limits.
  • Utilize Custom Settings and Custom Metadata to reduce repetitive queries.
  • Optimize trigger code and follow best practices for bulk processing.

By applying these strategies, you can manage and work around Salesforce governor limits effectively.


Question : Why apex callout is always asyc

Answer :

In Salesforce, Apex callouts are always asynchronous because of how Salesforce is designed to work efficiently for many users at the same time. Here’s a simple explanation:

  1. Shared Resources: Salesforce servers are shared by many customers. If one customer makes a long call to an external system and waits for the response, it can slow down the system for everyone else. Asynchronous callouts help avoid this problem by not making anyone wait.

  2. Avoiding Delays: Callouts to external systems can take a long time. If the system had to wait for these callouts to finish, it would slow down everything else. By making callouts asynchronous, Salesforce allows other tasks to continue while waiting for the external response.

  3. Limits on Processing Time: Salesforce has rules to prevent any single operation from taking too long (usually no more than 10 seconds). If a callout took longer than this, it could cause errors. Asynchronous callouts help stay within these time limits.

  4. Better User Experience: Users can keep using Salesforce without delays. When callouts are done in the background, users don’t have to wait for them to finish before doing other tasks.

Example

Think of it like this: If you call a friend for help and have to wait on hold for a long time, you can’t do anything else until they answer. Instead, you send them a message (asynchronous) and continue with your tasks. When they reply, you can read the message and act on it without having wasted time waiting.

How to Use Asynchronous Callouts

Here’s a simple example using an @future method, which is a way to tell Salesforce to do something in the background:

public class CalloutExample {
    @future(callout=true)
    public static void makeCallout() {
        Http http = new Http();
        HttpRequest request = new HttpRequest();
        request.setEndpoint('https://api.example.com/data');
        request.setMethod('GET');
        
        try {
            HttpResponse response = http.send(request);
            if (response.getStatusCode() == 200) {
                // Process the response
                System.debug(response.getBody());
            } else {
                System.debug('Callout failed with status: ' + response.getStatusCode());
            }
        } catch (Exception e) {
            System.debug('Callout failed: ' + e.getMessage());
        }
    }
}

In this example, the makeCallout method will run in the background, allowing other tasks to continue without waiting for the external call to finish.

In summary, asynchronous callouts help Salesforce work smoothly and efficiently for everyone by handling external communications in the background.


Question : SECURITY_ENFORCE use in SOQL

Answer :

In Salesforce Apex, the WITH SECURITY_ENFORCED clause is used in SOQL queries to ensure that the query respects the user's field-level security (FLS) and object-level security (OLS) settings. This means that the query will only return fields and objects that the user has permission to access. This feature enhances security by preventing unauthorized access to sensitive data.

Here’s an example of how to use WITH SECURITY_ENFORCED in a SOQL query:

Example: Basic Usage

public List<Account> getAccounts() {
    try {
        List<Account> accounts = [
            SELECT Id, Name, Phone, Industry 
            FROM Account 
            WITH SECURITY_ENFORCED
        ];
        return accounts;
    } catch (Exception e) {
        System.debug('Exception: ' + e.getMessage());
        return null;
    }
}

Example: Handling Security Exceptions

When using WITH SECURITY_ENFORCED, if the user doesn't have access to the fields or objects specified in the query, a QueryException will be thrown. You should handle this exception appropriately:

public List<Account> getAccounts() {
    try {
        List<Account> accounts = [
            SELECT Id, Name, Phone, Industry 
            FROM Account 
            WITH SECURITY_ENFORCED
        ];
        return accounts;
    } catch (QueryException qe) {
        System.debug('Query Exception: ' + qe.getMessage());
        // Handle lack of permissions
        return null;
    } catch (Exception e) {
        System.debug('General Exception: ' + e.getMessage());
        return null;
    }
}

Question : Security question on Triggers

Answer :

To handle security in Apex triggers, follow these key strategies:

  1. Field-Level and Object-Level Security (FLS and OLS)

    • Check if the user has access to specific fields and objects before performing operations.
    • Example:
      if (!Schema.sObjectType.Account.isAccessible()) {
          System.debug('Access to Account object is denied.');
          return;
      }
      for (Account acc : Trigger.new) {
          if (Schema.sObjectType.Account.fields.Name.isAccessible()) {
              System.debug('Account Name: ' + acc.Name);
          }
      }
  2. Use with sharing and without sharing Keywords

    • Use with sharing to enforce sharing rules and without sharing to bypass them in Apex classes called by triggers.
    • Example:
      public with sharing class AccountTriggerHandler {
          public static void handleBeforeUpdate(List<Account> newAccounts) {
              for (Account acc : newAccounts) {
                  System.debug('Handling Account: ' + acc.Name);
              }
          }
      }
      
      trigger AccountTrigger on Account (before update) {
          AccountTriggerHandler.handleBeforeUpdate(Trigger.new);
      }
  3. Custom Permissions

    • Check if the user has specific custom permissions to control feature access.
    • Example:
      if (!FeatureManagement.checkPermission('Manage_Accounts')) {
          System.debug('User does not have Manage Accounts permission.');
          return;
      }
  4. Context Awareness

    • Understand when your code runs in system context (ignoring user permissions) versus user context (respecting user permissions). Use without sharing sparingly.

By using these strategies, you ensure that your triggers respect user permissions and maintain data security.


Question : PMD violations

Answer :

PMD (Programming Mistake Detector) can also be used to analyze Apex code, the programming language used in Salesforce. Apex PMD helps identify common programming flaws specific to Apex development. Here are some common types of PMD violations in Apex and how to fix them:

  1. ApexUnitTestClassShouldHaveAsserts

    • Violation: Test classes should have assertions to verify the behavior of the code.
    • Fix: Add assertions to your test methods.
    // Before
    @IsTest
    private class MyTestClass {
        @IsTest
        static void testMethod() {
            // Test code without assertions
        }
    }
    
    // After
    @IsTest
    private class MyTestClass {
        @IsTest
        static void testMethod() {
            // Test code
            System.assertEquals(expectedValue, actualValue);
        }
    }
  2. AvoidLogicInTrigger

    • Violation: Triggers should not contain complex logic. Instead, use helper classes.
    • Fix: Move the logic to a handler or helper class.
    // Before
    trigger MyTrigger on Account (before insert, before update) {
        for (Account acc : Trigger.new) {
            if (acc.Name == 'Test') {
                acc.Description = 'This is a test account';
            }
        }
    }
    
    // After
    trigger MyTrigger on Account (before insert, before update) {
        MyTriggerHandler.handleTrigger(Trigger.new);
    }
    
    public class MyTriggerHandler {
        public static void handleTrigger(List<Account> accounts) {
            for (Account acc : accounts) {
                if (acc.Name == 'Test') {
                    acc.Description = 'This is a test account';
                }
            }
        }
    }
  3. AvoidUnusedLocalVariables

    • Violation: Declaring variables that are not used.
    • Fix: Remove the unused variables.
    // Before
    public class MyClass {
        public void myMethod() {
            Integer unusedVar = 10;
            // Some code
        }
    }
    
    // After
    public class MyClass {
        public void myMethod() {
            // Some code
        }
    }
  4. AvoidSoqlInLoops

    • Violation: Performing SOQL queries inside loops can cause governor limits to be exceeded.
    • Fix: Move the SOQL query outside the loop.
    // Before
    public class MyClass {
        public void myMethod(List<Id> accountIds) {
            for (Id accId : accountIds) {
                Account acc = [SELECT Name FROM Account WHERE Id = :accId];
                // Some code
            }
        }
    }
    
    // After
    public class MyClass {
        public void myMethod(List<Id> accountIds) {
            Map<Id, Account> accounts = new Map<Id, Account>([SELECT Name FROM Account WHERE Id IN :accountIds]);
            for (Id accId : accountIds) {
                Account acc = accounts.get(accId);
                // Some code
            }
        }
    }
  5. CyclomaticComplexity

    • Violation: Methods that are too complex.
    • Fix: Refactor the method to reduce complexity.
    // Before
    public class MyClass {
        public void complexMethod() {
            if (condition1) {
                // Some code
            } else if (condition2) {
                // Some code
            } else {
                // Some code
            }
        }
    }
    
    // After
    public class MyClass {
        public void complexMethod() {
            if (condition1) {
                handleCondition1();
            } else if (condition2) {
                handleCondition2();
            } else {
                handleOtherConditions();
            }
        }
    
        private void handleCondition1() {
            // Some code
        }
    
        private void handleCondition2() {
            // Some code
        }
    
        private void handleOtherConditions() {
            // Some code
        }
    }
  6. ApexCRUDViolation

    • Violation: Not checking for CRUD permissions before performing DML operations.
    • Fix: Use Schema.sObjectType methods to check for permissions.
    // Before
    public class MyClass {
        public void myMethod() {
            Account acc = new Account(Name = 'Test');
            insert acc;
        }
    }
    
    // After
    public class MyClass {
        public void myMethod() {
            if (Schema.sObjectType.Account.isCreateable()) {
                Account acc = new Account(Name = 'Test');
                insert acc;
            } else {
                // Handle lack of permissions
            }
        }
    }

Fixing these PMD violations in Apex helps improve code quality, readability, performance, and ensures compliance with Salesforce best practices. Regularly running PMD on your Apex codebase is a good practice to maintain high-quality code.


Question : Imperative apex

Answer :

Imperative Apex is essential for scenarios requiring detailed control over the application's behavior, enabling developers to implement complex, custom functionality beyond the capabilities of declarative tools.


Question : Difference between aura and LWC component

Answer :

image


Optum

Question : Apex flex queue

Answer :


Question : Custom permission

Answer :


Question : LWC component - configuration from salesforce page layout

Answer :


Question : New features in salesforce new release

Answer :


Question : Batch apex

Answer :


Question : Future and queueable apex

Answer :


Question : How to start second batch class after 15 mins to complete first batch class.

Answer :


Question : What is the difference between SOQL and Database.querylocator.

Answer :


Question : Wire vs imperative

Answer :


Question : LDS (Lightning Data Service)

Answer :


Question : Can we use DML in wire

Answer :


Question : Why we can not use DML in wire ?

Answer :


Question : Inbound and outbound

Answer :


Question : Process for inbound integration

Answer :


Question : Record lock error in salesforce

Answer :


Question : Is wire will be user mode or system mode

Answer :


Abbott

Question : what are types of relationships in salesforce

Answer :


Question : what is the difference between look up and master detail relationship

Answer :


Question : How to set up communication between salesforce and third party application

Answer :


Question : what is named credentials

Answer :


Question : what are connected apps

Answer :


Question : Questions related to inbound and outbound integration

Answer :


Question : what are the best practices while writing test class

Answer :


Question : what is the significance of start test and stoptest

Answer :


Question : what are the best practices while writing triggers

Answer :


Question : what is recursion in triggers and how to avoid it

Answer :


Question : what are asynchronous processes in salesforce

Answer :


Question : Scenario : Hands on with screen share

There is one field - Type Large Text area on Account Object. we need to get first name of all the contacts related to that account. Write a trigger for above scenario.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published