SoC and the Apex Common Library Tutorial Series Part 7: The Service Layer

https://youtu.be/5tM_MHV1ypY

What is the Service Layer?

The Service Layer, “Defines an application’s boundaries with a layer of services that establishes a set of available operations and coordinates the application’s response in each operation”. – Martin Fowler

This essentially just means that the service layer should house your business logic. It should be a centralized place that holds code that represents business logic for each object (database table) or the service layer logic for a custom built app in your org (more common when building managed packages).

Difference between the Service Layer and Domain Layer – People seem to often confuse this layer with the Domain layer. The Domain layer is only for object specific default operations (triggers, validations, updates that should always execute on a database transaction, etc). The Service layer is for business logic for major modules/applications in your org. Sometimes that module is represented by an object, sometimes it is represented by a grouping of objects. Domain layer logic is specific to each individual object whereas services often are not.


Service Layer Naming Conventions

Class Names – Your service classes should be named after the area of the application your services represent. Typically services classes are created for important objects or applications within your org.

Service Class Name Examples (Note that I prefer underscores in class names, this is just personal preference):

Account_Service 
DocumentGenerationApp_Service

Method Names – The public method names should be the names of the business operations they represent. The method names should reflect what the end users of your system would refer to the business operation as. Service layer methods should also ideally always be static.

Method Parameter Types and Naming – The method parameters in public methods for the service layer should typically only accept collections (Map, Set, List) as the majority of service layer methods should be bulkified (there are some scenarios however that warrant non-collection types). The parameters should be named something that reflects the data they represent.

Service Class Method Names and Parameter Examples:

public static void calculateOpportunityProfits(List<Account> accountsToCalculate)
public static void generateWordDocument(Map<String, SObject> sObjectByName)

Service Layer Security

Service Layer Security Enforcement – Service layers hold business logic so by default they should at minimum use inherited sharing when declaring the classes, however I would suggest always using with sharing and allowing developers to elevate the code to run without sharing when necessary by using a private inner class.

Example Security for a Service Layer Class:

public with sharing class Account_Service{
    public static void calculateOpportunityProfits(List<Account> accountsToCalculate){
        //code here
        new Account_Service_WithoutSharing().calculateOpportunityProfits_WithoutSharing(accountsToCalculate);
    }

    private without sharing class Account_Service_WithoutSharing{
        public void calculateOpportunityProfits_WithoutSharing(List<Account> accountsToCalculate){
            //code here
        }
    }
}

Service Layer Code Best Practices

Keeping the code as flexible as possible

You should make sure that the code in the service layer does not expect the data passed to it to be in any particular format. For instance, if the service layer code is expecting a List of Accounts that has a certain set of fields filled out, your service method has just become very fragile. What if the service needs an additional field on that list of accounts to be filled out in the future to do its job? Then you have to refactor all the places building lists of data to send to that service layer method.

Instead you could pass in a set of Account Ids, have the service method query for all the fields it actually requires itself, and then return the appropriate data. This will make your service layer methods much more flexible.

Transaction Management

Your service layer method should handle transaction management (either with the unit of work pattern or otherwise) by making sure to leverage Database.setSavePoint() and using try catch blocks to rollback when the execution fails.

Transaction management example

public static void calculateOpportunityProfits(Set<Id> accountIdsToCalculate){
        List<Account> accountsToCalculate = [SELECT Id FROM Account WHERE Id IN : accountIdsToCalculate];
        System.Savepoint savePoint = Database.setSavePoint();
        try{
            database.insert(accountsToCalculate);
        }
        catch(Exception e){
            Database.rollback(savePoint);
            throw e;
        }
}

Compound Services

Sometimes code needs to call more than one method in the service layer of your code. In this case instead of calling both service layer methods from your calling code like in the below example, you would ideally want to create a compound service method in your service layer.

Example calling both methods (not ideal)

try{
    Account_Service.calculateOpportunityProfits(accountIds);
    Account_Service.calculateProjectedOpportunityProfits(accountIds);
}
catch(Exception e){
    throw e;
}

The reason the above code is detrimental is that you would either have one of two side effects. The transaction management would only be separately by each method and one could fail and the other could complete successfully, despite the fact we don’t actually want that to happen. Alternatively you could handle transaction management in the class calling the service layer, which isn’t ideal either.

Instead we should create a new method in the service layer that combines those methods and handles the transaction management in a cleaner manner.

Example calling the compound method

try{
    Account_Service.calculateRealAndProjectedOpportunityProfits(accountIds);
}
catch(Exception e){
    throw e;
}

Implementing the Service Layer

To find out how to implement the Service Layer using the Apex Common Library, continue reading here: Implementing the Service Layer with the Apex Common Library . If you’re not interested in utilizing the Apex Common Library, no worries, there are really no frameworks to implement a Service Layer (to my knowledge) because this is literally just a business logic layer so every single orgs service layer will be different. The only thing Apex Common assists with here is abstracting the service layer to assist with Unit Test mocking and to make your service class instantiations more dynamic.

Libraries That Could Be Used for the Service Layer

None to my knowledge although the Apex Common Library provides a good foundation for abstracting your service layers to assist with mocking and more dynamic class instantiations.


Service Layer Examples

Apex Common Example (Suggested)

All three of the below classes are tied together. We’ll go over how this works in the next section.

Task Service Interface

Task Service Class

Task Service Implementation Class


Next Section

Part 8: Implementing the Service Layer with the Apex Common Library

SoC and the Apex Common Library Tutorial Series Part 6: The fflib_SObjectUnitOfWork Class


What is the fflib_SObjectUnitOfWork class?

It is a foundation built to allow you to leverage the unit of work design pattern from within Salesforce. Basically this class is designed to hold your database operations (insert, update, etc) in memory until you are ready to do all of your database transactions in one big transaction. It also handles savepoint rollbacks to ensure data consistentcy. For instance, if you are inserting Opportunities with Quotes in the same database (DML) transaction, chances are you don’t wanna insert those Opportunities if your Quotes fail to insert. The unit of work class is setup to automatically handle that transaction management and roll back if anything fails.

If also follows bulkification best practices to make your life even easier dealing with DML transactions.


Why is this class used?

This class is utilized so that you can have super fine control over your database transactions and so that you only do DML transactions when every single record is prepped and ready to be inserted, updated, etc.

Additionally there are two reasons it is important to leverage this class (or a class like it):
1) To allow for DML mocking in your test classes.
2) To massively reduce duplicate code for DML transactions in your org.
3) To make DML transaction management consistent

Think about those last two for a second… how many lines of code in your org insert, update, upsert (etc) records in your org? Then think about how much code also error handles those transaction and (if you’re doing things right) how much code goes into savepoint rollbacks. That all adds up over time to a ton of code. This class houses it all in one centralized apex class. You’ll never have to re-write all that logic again.


How to Register a Callback method for an Apex Commons UOW

The following code example shows you how to setup a callback method for your units of work using the fflib_SObjectUnitOfWork.IDoWork interface, should you need them.

public inherited sharing class HelpDeskAppPostCommitLogic implements fflib_SObjectUnitOfWork.IDoWork{
    List<Task> taskList;
    
    public HelpDeskAppPostCommitLogic(List<Task> taskList){
        this.taskList = taskList; 
    }
    
    public void doWork(){
        //write callback code here
    }
}

The code below shows you how to actually make sure your unit of work calls your callback method.

fflib_ISObjectUnitOfWork uow = Helpdesk_Application.helpDeskUOW.newInstance();
//code to create some tasks
uow.registerNew(newTasks);
uow.registerWork(new HelpDeskAppPostCommitLogic(newTasks));
uow.commitWork();    

Apex Commons Unit of Work Limitations

1) Records within the same object that have lookups to each other are currently not supported. For example, if the Account object has a Lookup to itself, that relationship cannot be registered.

2) You cannot do all or none false database transactions without creating a custom IDML implementation.

Database.insert(acctList, false);

3) To send emails with the Apex Commons UOW you must utilize the special registerEmail method.

4) It does not manage FLS and CRUD without implementing a custom class that implements the IDML interface and does that for you.

To do these things in your own way you would need to make a new class that implements the fflib_SObjectUnitOfWork’s IDML interface which we’ll cover below


How and When to use the fflib_SObjectUnitOfWork IDML Interface

If your unit of work needs a custom implementation for inserting, updating, deleting, etc that is not supported by the SimpleDML inner class then you are gonna want to create a new class that implements the fflib_SObjectUnitOfWork.IDML interface. After you create that class if you were using the Application factory you would instantiate your unit of work like so Application.uow.newInstance(new customIDMLClass()); otherwise you would initialize it using public static fflib_SObjectUnitOfWork uow = new fflib_SObjectUnitOfWork(new List<SObjectType>{Case.SObjectType}, new customIDMLClass());. A CUSTOM IDML CLASS IS SUPER IMPORTANT IF YOU WANT TO MANAGE CRUD AND FLS!!! THE fflib_SObjectUnitOfWork class does not do that for you! So let’s check out an example of how to implement a custom IDML class together below.

Example of an IDML Class

//Implementing this class allows you to overcome to limitations of the regular unit of work class.
public with sharing class IDML_Example implements fflib_SObjectUnitOfWork.IDML
{
    public void dmlInsert(List<SObject> objList){
        //custom insert logic here
    }
    public void dmlUpdate(List<SObject> objList){
        //custom update logic here
    }
    public void dmlDelete(List<SObject> objList){
        //custom delete logic here
    }
    public void eventPublish(List<SObject> objList){
        //custom event publishing logic here
    }
    public void emptyRecycleBin(List<SObject> objList){
        //custom empty recycle bin logic here
    }
}

fflib_SObjectUnitOfWork class method cheat sheet

This does not encompass all methods in the fflib_SObjectUnitOfWork class, however it does cover the most commonly used methods. There are also methods in this class to publish platform events should you need them but they aren’t covered below.

1) registerNew(SObject record) Registers a single record as a new record that need to be inserted.
2)
registerNew(List<SObject> records) – Registers a list of records as new records that need to be inserted.
3)
registerNew(SObject record, Schema.SObjectField relatedToParentField, SObject relatedToParentRecord) Registers a new record that needs to be inserted with a parent record relationship (this parent needs to have also been registered as a new record in your unit of work).
4)
registerRelationship(SObject record, Schema.SObjectField relatedToField, SObject relatedTo) Registers a relationship between two records that have yet to be inserted into the database. Both records need to be registered in your unit of work.
5)
registerRelationship( Messaging.SingleEmailMessage email, SObject relatedTo ) This method will allow you to register a relationship between an email message and a record. Both the email message and the record need to be registered in your unit of work to allow this to work.
6)
registerRelationship(SObject record, Schema.SObjectField relatedToField, Schema.SObjectField externalIdField, Object externalId) This method can be used to register a relationship between one record and another using an external id field. There is an example of how to implement this in the comments for this method linked above.
7)
registerDirty(SObject record) Registers a single record to be updated.
8) registerDirty(List records, List dirtyFields) This method should be used if you believe you’ve already registered a list of records to be updated by your unit of work and some of that records fields have been updated. This basically merges those new field updates into your already registered record.
9)
registerDirty(SObject record, List dirtyFields) This method should be used if you believe you’ve already registered a record to be updated by your unit of work and some of that records fields have been updated. This basically merges those new field updates into your already registered record.
10)
registerDirty(SObject record, Schema.SObjectField relatedToParentField, SObject relatedToParentRecord) This method is used to register an update to a record while also registering a new relationship to another record that has been registered as a new record in the same unit of work.
11)
registerDirty(List<SObject> records) This method is used to register a list of records to be updated.
12)
registerUpsert(SObject record) This method is used to register a single record to be upserted.
13) registerUpsert(List<SObject> records) This method is used to register a list of records for an upsert.
14) registerDeleted(SObject record) Registers a single record to be deleted.
15) registerDeleted(List<SObject> records) Registers a list of records to be deleted.
16)
registerPermanentlyDeleted(List<SObject> records) Registers a list of records to be permanently deleted. Basically it deletes records and then removes them from the recycle bin as well.
17)
registerPermanentlyDeleted(SObject record) Registers a record to be permanently deleted from the org. Basically it deletes records and then removes them from the recycle bin as well.
18)
registerEmptyRecycleBin(SObject record) This registers a record to be permanently deleted from the system by both deleting it and emptying it from the recycle bin.
19) public void registerEmptyRecycleBin(List<SObject> records) This takes a list of records and permanently deletes them from the system.
20) registerEmail(Messaging.Email email) Registers an email message to be sent
21) registerWork(IDoWork work) Registers a callback method to be called after your work has been committed to the database.
22) commitWork() Commits your unit of work (records registered) to the database. This should always be called last.


Next Section

Part 7: The Service Layer

SoC and the Apex Common Library Tutorial Series Part 5: The Unit of Work Pattern

What is the Unit of Work Pattern (UOW)

A Unit of Work, “Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems”.

The goal of the unit of work pattern is to simplify DML in your code and only commit changes to the database/objects when it’s truly time to commit. Considering the many limits around DML in Salesforce, it’s important to employ this pattern in your org in some way. It’s also important to note that this, “maintains a list of objects affected by a business transaction”, which indicates that the UOW pattern should be prevalent in your service layer (The service layer houses business logic).

The UOW pattern also ensures we don’t have data inconsistencies in our Salesforce instance. It does this by only committing work when all the DML operations complete successfully. It rolls back our transactions when any DML fails in our unit of work.


Benefits of the using the Unit of Work Pattern in Salesforce

There are several, but here are the biggest of them all… massive amounts of code reduction, having consistency with your DML transactions, doing the minimal DML statements feasible (bulkification) and DML mocking in unit tests. Let’s figure out how we reduce the code and make it more consistent first.

The Code Reduction and Consistency

Think about all the places in your codebase where you insert records, error handle the inserting of your records and manage the transactional state of your records (Savepoints). Maybe if your org is new there’s not a ton happening yet, but as it grows the amount of code dealing with that can become enormous and, even worse, inconsistent. I’ve worked in 12 year old orgs that had 8000+ lines of code just dedicated to inserting records throughout the system and with every dev who wrote the code a new variety of transaction management took place, different error handling (or none at all), etc.

Code Bulkification

The unit of work pattern also helps a great deal with code bulkification. It encourages you to to finish creating and modifying 100% of your records in your transaction prior to actually committing them (doing the dml transactions) to the database (objects). It makes sure that you are doing that absolute minimal transactions necessary to be successful. For instance, maybe for some reason in your code you are updating cases in one method, and when you’re done you call another method and it updates those same cases… why do that? You could register all those updates and update all those cases at once with one DML statement. Whether you realize it at the time or not, even dml statement counts… use them sparingly.

DML Mocking for Unit Tests

If you’re not sure what mocking and unit test are, then definitely check out my section on that in the wiki here. Basically, in an ideal scenario you would like to do unit testing, but unit testing depends on you having the ability to mock classes for you tests (basically creating fake versions of your class you have complete control over in your tests). Creating this layer that handles your dml transactions allows you to mock that layer in your classes when doing unit tests… If this is confusing, no worries, we’ll discuss it a bunch more later in the last three sections of this wiki.


Next Section

Part 6: The fflib_SObjectUnitOfWork Class

SoC and the Apex Common Library Tutorial Series Part 4: The fflib_Application Class

What is the fflib_Application class?

Quality question… I mean honestly wtf is this thing? Lol, sorry, let’s figure it out together. The fflib_Application class is around for two primary purposes. The first is to allow you an extremely abstract way of creating new instances of your unit of work, service layer, domain layer and selector layer in the Apex Common Library through the use of the factory pattern. The second is that implementing this application class is imperative if you want to leverage the Apex Mocks unit testing library. It depends on this Application Factory being implemented.

Most importantly though, if you understand how interfaces, inheritance and polymorphism work implementing this class allows you to write extremely abstract Salesforce implementations, which we’ll discuss more in sections below


Why is this class used?

Ok, if we ignore the fact that this is required for us to use the Apex Mocks library, understanding the power behind this class requires us to take a step back and formulate a real world Salesforce use case for implementing it… hopefully the following one will be easy for everyone to understand.

Say for instance I have a decent sized Salesforce instance and our business has a use case to create tasks across multiple objects and the logic for creating those tasks are unique to every single object. Maybe on the Account object we create three new tasks every single time we create an account and on the Contact object we create two tasks every single time a record is created or updated in a particular way and we ideally want to call this logic on the fly from anywhere in our system.

No matter what we should probably place the task creation logic in our domain layer because it’s relevant to each individual object, but pretend for a second that we have like 20 different objects we need this kind of functionality on. Maybe we need the executed logic in an abstract “task creator” button that can be placed on any lightning app builder page and maybe some overnight batch jobs need to execute the logic too.

Well… what do we do? Let’s just take the abstract “Task Creator” button we might want to place on any object in our system. We could call each individual domain layer class’s task creation logic in the code based on the object we were on (code example below), but that logic tree could get massive and it’s not super ideal.

Task Service example with object logic tree

public with sharing class Task_Service_Impl
{
	//This method calls the task creators for each object type
	public void createTasks(Set recordIds, Schema.SObjectType objectType)
	{
            if(objectType == Account.getSObjectType()){
                new Accounts().createTasks(recordIds);
            }
            else if(objectType == Case.getSObjectType()){
                new Cases().createTasks(recordIds);
            }
            else if(objectType == Opportunity.getSObjectType()){
                new Opportunities().createTasks(recordIds);
            }
            else if(objectType == Taco__c.getSObjectType()){
                new Tacos().createTasks(recordIds);
            }
            else if(objectType == Chocolate__c.getSObjectType()){
                new Chocolates().createTasks(recordIds);
            }
            //etc etc for each object could go on for decades
        }
}

Maybe… just maybe there’s an easier way. This is where the factory pattern and the fflib_Application class come in handy. Through the use of the factory pattern we can create an abstract Task Service that can (based on a set of records we pass to it) select the right business logic to execute in each domain layer dynamically.

Task Service example with the factory pattern (example with a ton of comments explaining this here)

//Creation of the Application factory class
public with sharing class Application
{
	public static final fflib_Application.ServiceFactory service =
			new fflib_Application.ServiceFactory(
			new Map<Type, Type>{
				Task_Service_Interface.class => Task_Service_Impl.class}
			);

	public static final fflib_Application.DomainFactory domain =
	new fflib_Application.DomainFactory(
		Application.selector,
		new Map<SObjectType, Type>{Case.SObjectType => Cases.Constructor.class,
		Opportunity.SObjectType => Opportunities.Constructor.class,
                Account.SObjectType => Accounts.Constructor.class,
                Taco__c.SObjectType => Tacos.Constructor.class,
                Chocolate__c.SObjectType => Chocolates.Constructor.class}
	);
}
//The task service that anywhere can call and it will operate as expected with super minimal logic
public with sharing class Task_Service_Impl implements Task_Service_Interface
{
        //This method calls the task creators for each object type
    public void createTasks(Set<Id> recordIds, Schema.SObjectType objectType)
    {
        fflib_ISObjectDomain objectDomain = Application.domain.newInstance(recordIds);

        if(objectDomain instanceof Task_Creator_Interface){
            Task_Creator_Interface taskCreator = (Task_Creator_Interface)objectDomain;
            taskCreator.createTasks(recordIds);
        }
    }
}

You might be lookin at the two code examples right now like wuttttttttt how thooooo?? And I just wanna say, I fully understand that. The first time I saw this implemented I thought the same thing, but it’s a pretty magical thing. Thanks to the newInstance() methods on the fflib_Application class and the Task_Creator_Interface we’ve implemented on the domain classes, you can dynamically generate the correct domain when the code runs and call the create tasks method. Pretty wyld right? Also if you’re thinkin, “Yea that’s kinda nifty Matt, but you had to create this Application class and that’s a bunch of extra code.” you need to step back even farther. This Application factory can be leveraged ANYWHERE IN YOUR ENTIRE CODEBASE! Not just locally in your service class. If you need to implement something similar to automatically generate opportunities or Accounts or something from tons of different objects you can leverage this exact same Application class there. In the long run, this ends up being wayyyyyyyyy less code.

If you want a ton more in depth explanation on this, please watch the tutorial video. We code a live example together so I can explain this concept. It’s certainly not easy to grasp at first glance.


fflib_Application inner classes and methods cheat sheet

Inside the fflib_Application class there are four classes that represent factories for the your unit of work, service layer, domain layer and selector layer.

Let’s go over them and how they work:

The Unit of Work Factory

Inside the fflib_Application class there is the UnitOfWorkFactory class. Let’s first figure out how to instantiate this class:

//The constructor for this class requires you to pass a list of SObject types in the dependency order. So in this instance Accounts would always be inserted before your Contacts and Contacts before Cases, etc.
public static final fflib_Application.UnitOfWorkFactory UOW =
		new fflib_Application.UnitOfWorkFactory(
			new List<SObjectType>{
                        Account.SObjectType,
                        Contact.SObjectType,
			Case.SObjectType,
			Task.SObjectType}
	);

After creating this unit of work variable above ^ in your Application class example here there are four important new instance methods you can leverage to generate a new unit of work:

1) newInstance() – This creates a new instance of the unit of work using the SObjectType list passed in the constructor.

newInstance() Example Method Call

public with sharing class Application
{
    public static final fflib_Application.UnitOfWorkFactory UOW =
		new fflib_Application.UnitOfWorkFactory(
			new List<SObjectType>{
                        Account.SObjectType,
                        Contact.SObjectType,
			Case.SObjectType,
			Task.SObjectType}
    );
}

public with sharing class SomeClass{
    public void someClassMethod(){
         fflib_ISObjectUnitOfWork unitOfWork = Application.UOW.newInstance();
    }
}

2) newInstance(fflib_SObjectUnitOfWork.IDML dml) – This creates a new instance of the unit of work using the SObjectType list passed in the constructor and a new IDML implementation to do custom DML work not inherently supported by the fflib_SObjectUnitOfWork class. More info on the IDML interface here

newInstance(fflib_SObjectUnitOfWork.IDML dml) Example Method Call

public with sharing class Application
{
    public static final fflib_Application.UnitOfWorkFactory UOW =
		new fflib_Application.UnitOfWorkFactory(
			new List<SObjectType>{
                        Account.SObjectType,
                        Contact.SObjectType,
			Case.SObjectType,
			Task.SObjectType}
    );
}

//Custom IDML implementation
public with sharing class IDML_Example implements fflib_SObjectUnitOfWork.IDML
{
    void dmlInsert(List<SObject> objList){
        //custom insert logic here
    }
    void dmlUpdate(List<SObject> objList){
        //custom update logic here
    }
    void dmlDelete(List<SObject> objList){
        //custom delete logic here
    }
    void eventPublish(List<SObject> objList){
        //custom event publishing logic here
    }
    void emptyRecycleBin(List<SObject> objList){
        //custom empty recycle bin logic here
    }
}

public with sharing class SomeClass{
    public void someClassMethod(){
         fflib_ISObjectUnitOfWork unitOfWork = Application.UOW.newInstance(new IDML_Example());
    }
}

3) newInstance(List <SObjectType> objectTypes) – This creates a new instance of the unit of work and overwrites the SObject type list passed in the constructor so you can have a custom order if you need it.

newInstance(List <SObjectType> objectTypes) Example Method Call

public with sharing class Application
{
    public static final fflib_Application.UnitOfWorkFactory UOW =
		new fflib_Application.UnitOfWorkFactory(
			new List<SObjectType>{
                        Account.SObjectType,
                        Contact.SObjectType,
			Case.SObjectType,
			Task.SObjectType}
    );
}

public with sharing class SomeClass{
    public void someClassMethod(){
         fflib_ISObjectUnitOfWork unitOfWork = Application.UOW.newInstance(new List<SObjectType>{
                        Case.SObjectType,
                        Account.SObjectType,
                        Task.SObjectType,
                        Contact.SObjectType,
			});
    }
}

4) newInstance(List objectTypes, fflib_SObjectUnitOfWork.IDML dml) – This creates a new instance of the unit of work and overwrites the SObject type list passed in the constructor so you can have a custom order if you need it and a new IDML implementation to do custom DML work not inherently supported by the fflib_SObjectUnitOfWork class. More info on the IDML interface here.

newInstance(List objectTypes, fflib_SObjectUnitOfWork.IDML dml) Example Method Call

public with sharing class Application
{
    public static final fflib_Application.UnitOfWorkFactory UOW =
		new fflib_Application.UnitOfWorkFactory(
			new List<SObjectType>{
                        Account.SObjectType,
                        Contact.SObjectType,
			Case.SObjectType,
			Task.SObjectType}
    );
}

//Custom IDML implementation
public with sharing class IDML_Example implements fflib_SObjectUnitOfWork.IDML
{
    void dmlInsert(List<SObject> objList){
        //custom insert logic here
    }
    void dmlUpdate(List<SObject> objList){
        //custom update logic here
    }
    void dmlDelete(List<SObject> objList){
        //custom delete logic here
    }
    void eventPublish(List<SObject> objList){
        //custom event publishing logic here
    }
    void emptyRecycleBin(List<SObject> objList){
        //custom empty recycle bin logic here
    }
}

public with sharing class SomeClass{
    public void someClassMethod(){
         fflib_ISObjectUnitOfWork unitOfWork = Application.UOW.newInstance(new List<SObjectType>{
                        Case.SObjectType,
                        Account.SObjectType,
                        Task.SObjectType,
                        Contact.SObjectType,
			}, new IDML_Example());
    }
}

The Service Factory

Inside the fflib_Application class there is the ServiceFactory class. Let’s first figure out how to instantiate this class:

//This allows us to create a factory for instantiating service classes. You send it the interface for your service class
//and it will return the correct service layer class
//Exmaple initialization: Object objectService = Application.service.newInstance(Task_Service_Interface.class);
public static final fflib_Application.ServiceFactory service =
	new fflib_Application.ServiceFactory(new Map<Type, Type>{
		SObject_SharingService_Interface.class => SObject_SharingService_Impl.class
	});


After creating this service variable above ^ in your Application class example here there is one important new instance method you can leverage to generate a new service class instance:

1) newInstance(Type serviceInterfaceType) – This method sends back an instance of your service implementation class based on the interface you send in to it.

newInstance(Type serviceInterfaceType) Example method call:

//This is using the service variable above that we would've created in our Application class
Application.service.newInstance(Task_Service_Interface.class);

The Selector Factory

Inside the fflib_Application class there is the SelectorFactory class. Let’s first figure out how to instantiate this class:

//This allows us to create a factory for instantiating selector classes. You send it an object type and it sends
//you the corresponding selectory layer class.
//Example initialization: fflib_ISObjectSelector objectSelector = Application.selector.newInstance(objectType);
public static final fflib_Application.SelectorFactory selector =
	new fflib_Application.SelectorFactory(
		new Map<SObjectType, Type>{
			Case.SObjectType => Case_Selector.class,
			Contact.SObjectType => Contact_Selector.class,
			Task.SObjectType => Task_Selector.class}
	);

After creating this selector variable above ^ in your Application class example here there are three important methods you can leverage to generate a new selector class instance:

1) newInstance(SObjectType sObjectType) – This method will generate a new instance of the selector based on the object type passed to it. So for instance if you have an Opportunity_Selector class and pass Opportunity.SObjectType to the newInstance method you will get back your Opportunity_Selector class (pending you have configured it this way in your Application class map passed to the class.

newInstance(SObjectType sObjectType) Example method call:

//This is using the selector variable above that we would've created in our Application class
Application.selector.newInstance(Case.SObjectType);

2) selectById(Set<Id> recordIds) – This method, based on the ids you pass will automatically call your registered selector layer class for the set of ids object type. It will then call the selectSObjectById method that all Selector classes must implement and return a list of sObjects to you.

selectById(Set<Id> recordIds) Example method call:

//This is using the selector variable above that we would've created in our Application class
Application.selector.selectById(accountIdSet);

3) selectByRelationship(List<sObject> relatedRecords, SObjectField relationshipField) – This method, based on the relatedRecords and the relationship field passed to it will generate a selector layer class for the object type in the relationship field. So say you were querying the Contact object and you wanted an Account Selector class, you could call this method it, pass the list of contacts you queried for and the AccountId field to have an Account Selector returned to you (pending that selector was configured in the Application show above in this wiki article).

selectByRelationship(List<sObject> relatedRecords, SObjectField relationshipField) Example method call:

//This is using the selector variable above that we would've created in our Application class
Application.selector.selectByRelationship(contactList, Contact.AccountId);

The Domain Factory

Inside the fflib_Application class there is the DomainFactory class. Let’s first figure out how to instantiate this class:

//This allows you to create a factory for instantiating domain classes. You can send it a set of record ids and
//you'll get the corresponding domain layer.
//Example initialization: fflib_ISObjectDomain objectDomain = Application.domain.newInstance(recordIds);
public static final fflib_Application.DomainFactory domain =
	new fflib_Application.DomainFactory(
		Application.selector,
		new Map<SObjectType, Type>{Case.SObjectType => Cases.Constructor.class,
		Contact.SObjectType => Contacts.Constructor.class}
	);

After creating this domain variable above ^ in your Application class example here there are three important methods you can leverage to generate a new domain class instance:

1) newInstance(Set <Id> recordIds) – This method creates a new instance of your domain class based off the object type in the set of ids you pass it.

newInstance(Set<Id> recordIds) Example method call:

Application.domain.newInstance(accountIdSet);

2) newInstance(List<sObject> records) – This method creates a new instance of your domain class based off the object type in the list of records you pass it.

newInstance(List<sObject> records) Example method call:

Application.domain.newInstance(accountList);

3) newInstance(List<sObject> records, SObjectType domainSObjectType) – This method will create a newInstance of the domain class based on the object type and record list passed to it.

newInstance(List<sObject> records, SObjectType domainSObjectType) Example method call:

Application.domain.newInstance(accountList, Account.SObjectType);

The setMock Methods

In every factory class inside the fflib_Application class there is a setMock method. These methods are used to pass in mock/fake versions of your classes for unit testing purposes. Make sure to leverage this method if you are planning to do unit testing. Leveraging this method eliminates the need to use dependency injection in your classes to allow for mocking. There are examples of how to leverage this method in the Implementing Mock Unit Testing with Apex Mocks section of this wiki.


Next Section

Part 5: The Unit of Work Pattern

SoC and the Apex Common Library Tutorial Series Part 3: The Factory Method Pattern

What is the Factory Method Pattern?

The factory method pattern allows you to create objects (or instantiate classes) without having to specify the exact class that is being created. Say for instance you have a service class that can be called by multiple object types and those object types each have their own object specific implementation for creating tasks for them. Instead of writing a ton of if else’s in the service class to determine which class should be constructed, you could leverage the factory method pattern and massively reduce your code.


Why is it Useful?

It’s useful because if used appropriately it can massively reduce the amount of code in your codebase and will allow for a much more dynamic and flexible implementation. The amount of flexibility when used appropriately can be absolutely astounding. Let’s take a look at two different examples. One not using the factory pattern and another that does!

Creating Tasks for Different Objects (No Factory Pattern):

public with sharing class Task_Service_Impl
{
	//This method calls the task creators for each object type
	public void createTasks(Set<Id> recordIds, Schema.SObjectType objectType)
	{
            if(objectType == Account.getSObjectType()){

                //Accounts (and the other object types below) is not the same as the regular 
                //Account object. 
                //This is further explained in the domain layer section of this wiki. 
                //Basically you name your domain class
                //the plural version of the object the domain represents
                new Accounts().createTasks(recordIds);
            }
            else if(objectType == Case.getSObjectType()){
                new Cases().createTasks(recordIds);
            }
            else if(objectType == Opportunity.getSObjectType()){
                new Opportunities().createTasks(recordIds);
            }
            else if(objectType == Taco__c.getSObjectType()){
                new Tacos().createTasks(recordIds);
            }
            else if(objectType == Chocolate__c.getSObjectType()){
                new Chocolates().createTasks(recordIds);
            }
            //etc etc for each object could go on for decades
        }
}

Creating Tasks for Different Objects (Factory Pattern):

//The task service that anywhere can call and it will operate as expected with super minimal logic
public with sharing class Task_Service_Impl implements Task_Service_Interface
{
        //This method calls the task creators for each object type
	public void createTasks(Set<Id> recordIds)
	{
            //Using our Application class we are able to instantiate new instances of 
            //domain classes based on the recordIds we pass 
            //the newInstance method.
            //We cover the fflib_Application class and how it uses the factory pattern a 
            //ton more in the next section.
	    fflib_ISObjectDomain objectDomain = Application.domain.newInstance(recordIds);

	    if(objectDomain instanceof Task_Creator_Interface){
	        Task_Creator_Interface taskCreator = (Task_Creator_Interface)objectDomain;
		taskCreator.createTasks(recordIds);
	    }
	}
}

Right now you might be kinda shook… at least I know I was the first time I implemented it, lol. How on Earth is this possible?? How can so much code be reduced to so little? The first thing we do is instantiate a new domain class (domain classes are basically just kinda fancy trigger handlers, but more on that later) using our Application class (our factory class) simply by sending it record ids. The Application factory class generates the object specific Domain class by determining the set of recordIds object type using the Id.getSObjectType() method that Salesforce makes available in Apex. Then by implementing the Task_Creator_Interface interface on each of the objects domain classes I’m guaranteeing that if something is an instance of the Task_Creator_Interface they will have a method called createTasks! Depending on the use case this can take hundreds of lines of code and reduce it to almost nothing. It also helps in the Separation of Concerns area by making our services much more abstract. It delegates logic more to their respective services or domains instead of somewhere the logic probably doesn’t belong.


Where does it fit into Separation of Concerns?

Basically it reduces your need to declare concreate class/object types in your code in many places and it allows you to create extremely flexible and abstract services (more on this in the implementing the service layer with apex common section). Again take the example of task creation, maybe you have 15 controller classes (classes connected to a UI) in your org making tasks for 15 different objects and each object has a different task implementation, but you want to move all that task creation logic into a singular service class that anywhere can call for any object at any time. The factory method pattern is quite literally built for this scenario. In fact I have two examples below demonstrating it! One using a simple factory class to create tasks and one using the fflib_Application class to do the same thing.


Where is it used in the Apex Common Library

It’s leveraged heavily by the fflib_Application class, which you can find out more about here.


Example Code (Abstract Task Creation App)

The following code example in the repo is an example of how the factory pattern could work in a real world Salesforce implementation to allow for tasks to be created on multiple objects using a different implementation for each object.

Apex Common Abstract Task Creation App


Next Section

Part 4: The fflib_Application Class

SoC and the Apex Common Library Tutorial Series Part 2: Introduction to the Apex Common Library

https://youtu.be/3JmWECi77zU

What is the Apex Common Library?

The Apex Common Library is an open source library originally created by Andy Fawcett when he was the CTO of FinancialForce and currently upkept by many community members, but most notably John Daniel. Aside from its origins and the fflib_ in the class names, it is no longer linked to FinancialForce in any way.

The library was originally created because implementing the Separation of Concerns Design Principle is difficult no matter what tech stack you’re working in. For Salesforce, the Apex Common Library was built to simplify the process of implementing Separation of Concerns as well as assist in managing DML transactions, creating high quality unit tests (you need the Apex Mocks library to assist with this) and enforcing coding and security best practices. If you want an exceptionally clean, understandable and flexible code base, the Apex Common library will greatly assist you in those endeavors.


Does The Apex Common Library Implement Separation of Concerns for me Automatically?

Unfortunately it’s not that simple. This library doesn’t just automatically do this for you, no library could, but what it does is give you the tools to easily implement this design principle in your respective Salesforce Org or Managed Package. Though there are many more classes in the Apex Common Library, there are four major classes to familiarize yourself with to be able to implement this, four object oriented programming concepts and three major design patterns. Additionally it’s beneficial if you understand the difference between a Unit Test and an Integration Test. We’ll go over all of these things below.


The Four Major Classes

1) fflib_Application.cls This Application class acts as a way to easily implement the Factory pattern for building the different layers when running your respective applications within your org (or managed package). When I say “Application” for an org based implementation this could mean a lot of things, but think of it as a grouping of code that represents a specific section of your org. Maybe you have a service desk in your org, that service desk could be represented as an “Application”. This class and the factory pattern are also what makes the Apex Mocks Library work, without implementing it, Apex Mocks will not work.

2) fflib_SObjectDomain.cls This houses the base class that all Domain classes you create will extend. The many methods within this class serve to make your life considerably easier when building your domain classes, for each object that requires a trigger, out. You can check out my Apex Common Domain Layer Implementation Guide for more details.

3) fflib_SObjectSelector.cls This houses the base class that all Selector classes you create will extend. The many methods within this class will serve to make your life a ton easier when implementing a selector classes for your various objects in your org. You can check out my Apex Common Selector Layer Implementation Guide

4) fflib_SObjectUnitOfWork.cls This houses the logic to implement the Unit of Work design pattern in your code. There a ton of useful methods within it that will make your life developing on the platform quite a bit simpler. For more information on the fflib_SObjectUnitOfWork class and the concept itself, please refer to my guide on how to use the Unit of Work Pattern in Salesforce.


The Four Object Oriented Programming Concepts

1) Inheritance) – When a class inherits (or extends) another class and the sub class gets access to all of its publicly accessible methods and variables.

2) Polymorphism) – When a class uses overloaded methods or overrides an inherited classes methods.

3) Encapsulation) – Only publishing (or making public) methods and class variables that are needed for other classes to use it.

4) Interfaces) – An interface is a contract between it and a class that implements it to make sure the class has specific method signatures implemented.

More information on the difference between Inheritance and Polymorphism


The Four Design Patterns

1) The Factory Design Pattern – Used in the fflib_Application class
2) The Unit of Work Design Pattern – Used in the fflib_SObjectUnitOfWork class
3) The Template Method Design Pattern – Used in the fflib_SObjectDomain class
4) The Builder Pattern – Used in the fflib_SObjectSelector class


Next Section

Part 3: The Factory Pattern

SoC and the Apex Common Library Tutorial Series Part 1: Introduction to the Separation of Concerns Design Principle


What is the Separation of Concerns Design Principle?

Basically separation of concerns is the practice of putting logical boundaries on your code. Putting these logical boundaries on your code helps make your code easier to understand, easier to maintain and much more flexible when it needs to be altered (and every code base ever has to be altered all the time).

In the Salesforce Ecosystem there are three major areas of concern we ideally should separate our code into. They are the following:

The Service Layer:

The Service Layer should house 100% of your non-object specific business logic (object specific logic is most often handled by the domain layer). This is, the logic that is specific to your organizations specific business rules. Say for instance you have a part of your Salesforce App that focuses on Opportunity Sales Projections and the Opportunity Sales Projection App looks at the Oppotunity, Quote, Product and Account objects. You might make an OpportunitySalesProjection_Service apex class that houses methods that have business logic that is specific to your Opportunity Sales Projection App. More information on the Service Layer here.

The Domain Layer:

The Domain Layer houses your individual objects (database tables) trigger logic. It also houses object specific validation logic, logic that should always be applied on the insert of every record for an object and object specific business logic (like how a task my be created for a specific object type, etc). If you used the Account object in your org you should create a Domain class equivalent for the Account object through the use of a trigger handler class of some sort. More information on the Domain Layer here.

The Selector Layer:

The Selector Layer is responsible for querying your objects (database tables) in Salesforce. Selector layer classes should be made for each individual object (or grouping of objects) that you intend to write queries for in your code. The goal of the selector layer is to maintain query consistency (consistency in ordering, common fields queried for, etc) and to be able to reuse common queries easily and not re-write them over and over again everywhere.


Why is it Useful?

There are many benefits to implementing SoC, most of which were outlined above, but here are the highlights:

1) Modularizes your code into easy to understand packages of code making it easier to know what code controls what, why and when.

2) Massively reduces the amount of code in your org by centralizing your logic into different containers. For instance, maybe you currently have 13 different apex controllers that house similar case business logic. If you placed that business logic into a service class and had all 13 apex controllers call that service class instead your life would be a whole lot simpler. This can get a lot more abstract and turn into absolutely unprecedented code reduction, but we have to start somewhere a bit simpler.

3) Separation of Concerns lends itself to writing extremely well done and comprehensive Unit Tests. It allows for easy dependency injection which allows you to, in test classes, mock a classes dependent classes. We’ll go over this more when we get to the Unit testing and Apex Mocks section of this tutuorial, but if you want a quick and easy explanation, please feel free to check out my video covering dependency injection and mocking in apex.


How does the Apex Common Library help with SoC?

The Apex Common Library was quite literally built upon the three layers outlined above. It provides an unrivaled foundation to implement SoC in your Salesforce org. When I started this tutorial series I was not convinced it was the absolute best choice out there, but after hundreds of hours of practice, documentation, experimentation with other similar groupings of libraries, etc I feel I can confidently say (as of today) that this is something the community is lucky even exists and needs to be leveraged much more than it is today.


Example Code

All of the code examples in this repo are examples of SoC in action. You can check the whole repo out here. For layer specific examples check out the layer specific pages of this wiki.


Next Section

Part 2: Introduction to the Apex Common Library

Salesforce Development Tutorial(LWC): How to Generate a Word Document from a Lightning Web Component

Why Create an LWC that can Generate Word Documents?

This is a little more self explanatory than many of the blog posts I do, but let’s go over some things. You typically wanna create this because the business has a need (for one reason or another) to generate a word doc. I’ve had businesses need them so important people could sign off on something with a hand written signature, needed guest list printed for campaigns/events and several other scenarios.

As far as why we should use an LWC to do this instead of a VF Page or Aura Component, Aura Components are considerably slower and I would just suggest not making them anymore in general and VF Pages suffer from view state limitations. While it’s easier to deal with them when working with external libraries because of lightning locker service, it’s easy to generate a document with images that blows past the 170kb view state limit and then crashes your page.


The docx.js Javascript Library

To generate word documents, we need to use the docx.js javascript library, which thankfully, is locker service compliant! Saves us a lot of time (if you didn’t know you can modify most libraries to make them compliant). You can get the docxjs code we’re gonna be using for this tutorial here .

This library basically allows you to generate word documents using javascript. It makes your life doing this a thousand times easier, so make sure to thank the devs that built it!


Writing the Code

The code we’re gonna write to get this done is just for a simple example. We’re gonna generate a list of contacts associated with an account in a word document. Before we get started, all this code is up on my GitHub here, so if you wanna just ignore this whole section and check out the GitHub repo, feel free, otherwise, please carry on, lol. So first things first, open up VSCode and create a new lightning web component! If you aren’t familiar with how to setup VSCode, I have a video covering it here!

Once you’ve got your new LWC created in VSCode, we need to upload the docxjs code to static resources so that we can use it in our LWC. You can grab the docxjs code here. Then navigate to static resources in setup and upload the docxjs code there. Make sure to make the static resource public!

After that’s done, switch back over to VSCode and let’s import the docxjs file into the LWC by using the code below:

import { LightningElement} from 'lwc';
import {loadScript} from "lightning/platformResourceLoader";
import docxImport from "@salesforce/resourceUrl/docx";

export default class Contact_list_generator extends LightningElement {

    connectedCallback(){
        Promise.all([loadScript(this, docxImport)]).then(() =>{
            //call some code here
        });
    }
}

You may be looking at the above like, “wtf is that bro?” so let me explain. The connectedCallback method is called when your LWC is loaded into the browser, so it’s kinda like the init method in Aura components. Promise.all is just saying, “Hey, I promise to wait until all the scripts are loaded, then I’m gonna execute the code inside this code block”. The loadScript is a module that Salesforce provides to you that allows you to load in resources to your LWC from static resources. Last, but certainly not least, the, “import docxImport from “@salesforce/resourceUrl/docx”;” is the actual reference to your docx static resource file. The docx at the end of the of that line should be whatever you actually named your static resource.

Next let’s add the html below to our LWC

<template>
    <div class="slds-p-bottom_x-large">
        <lightning-button class="hidden slds-float_left slds-p-right_medium" onclick={startDocumentGeneration} label="Build Document"></lightning-button>
        <a href={downloadURL} download="ContactList.docx" class="slds-hide slds-button slds-button_brand slds-float_left" >Download Document</a>         
    </div>
</template>

In the HTML above we’re basically just creating two buttons, one to generate a word document and one to download that word document. You’ll notice there are two references in the HTML to js variables/methods that don’t exist yet (startDocumentGeneration and downloadURL) so let’s get back to the LWC js controller and figure this thing out.

The next thing we need to add is a way to render the generate document button after the component loads the docxjs script. We can do that with the following code

    connectedCallback(){
        Promise.all([loadScript(this, docxImport)]).then(() =>{
            this.renderButtons();
        });
    }

    renderButtons(){
        this.template.querySelector(".hidden").classList.remove("hidden");
    }

In our connected callback method we’re gonna call a method called renderButtons that changes the visibility of our buttons after our scripts are loaded. The “this.template.querySelector(“.hidden”).classList.remove(“hidden”);” is removing the class that was hiding the component and allowing it to be viewed and clickable. We do need to actually add the css though. So let’s add the css below to the component

.hidden{
    display: none;
}

Basically that css just allows you to hide an element… pretty simple. Not much there.

The next thing we need to do is create the startDocumentGeneration method and actually grab our contact data and build the document. So let’s look at the rest of the controller code we need to build out below.

import { LightningElement, api } from 'lwc';
import {loadScript} from "lightning/platformResourceLoader";
import docxImport from "@salesforce/resourceUrl/docx";
import contactGrab from "@salesforce/apex/ContactGrabber.getAllRelatedContacts";

export default class Contact_list_generator extends LightningElement {

    @api recordId;
    downloadURL;
    _no_border = {top: {style: "none", size: 0, color: "FFFFFF"},
	bottom: {style: "none", size: 0, color: "FFFFFF"},
	left: {style: "none", size: 0, color: "FFFFFF"},
	right: {style: "none", size: 0, color: "FFFFFF"}};

    connectedCallback(){
        Promise.all([loadScript(this, docxImport)]).then(() =>{
            this.renderButtons();
        });
    }

    renderButtons(){
        //this.template.querySelector(".hidden").classList.add("not_hidden");
        this.template.querySelector(".hidden").classList.remove("hidden");
    }

    startDocumentGeneration(){
        contactGrab({'acctId': this.recordId}).then(contacts=>{
            this.buildDocument(contacts);
        });
    }

    buildDocument(contactsPassed){
        let document = new docx.Document();
        let tableCells = [];
        tableCells.push(this.generateHeaderRow());

        contactsPassed.forEach(contact => {
            tableCells.push(this.generateRow(contact));
        });

        this.generateTable(document, tableCells);
        this.generateDownloadLink(document);
    }

    generateHeaderRow(){
        let tableHeaderRow = new docx.TableRow({
            children:[
                new docx.TableCell({
                    children: [new docx.Paragraph("First Name")],
                    borders: this._no_border
                }),
                new docx.TableCell({
                    children: [new docx.Paragraph("Last Name")],
                    borders: this._no_border
                }) 
            ]
        });

        return tableHeaderRow;
    }

    generateRow(contactPassed){
        let tableRow = new docx.TableRow({
            children: [
                new docx.TableCell({
                    children: [new docx.Paragraph({children: [this.generateTextRun(contactPassed["FirstName"].toString())]})],
                    borders: this._no_border
                }),
                new docx.TableCell({
                    children: [new docx.Paragraph({children: [this.generateTextRun(contactPassed["LastName"].toString())]})],
                    borders: this._no_border
                })
            ]
        });

        return tableRow;
    }

    generateTextRun(cellString){
        let textRun = new docx.TextRun({text: cellString, bold: true, size: 48, font: "Calibri"});
        return textRun;
    }

    generateTable(documentPassed, tableCellsPassed){
        let docTable = new docx.Table({
            rows: tableCellsPassed
        });

        documentPassed.addSection({
            children: [docTable]
        });
    }

    generateDownloadLink(documentPassed){
        docx.Packer.toBase64String(documentPassed).then(textBlob =>{
            this.downloadURL = 'data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,' + textBlob;
            this.template.querySelector(".slds-hide").classList.remove("slds-hide");
        });
    }
}

So, there’s a bit to cover here, lol, so let’s start with the call in to the apex controller to get our contacts. This line of code here:

contactGrab({'acctId': this.recordId}).then(contacts=>{
            this.buildDocument(contacts);
        });

This calls to the apex controller and retrieves a list of contacts based on the account id of the record we’re currently on. If you didn’t know, the @api recordId variable declaration at the top of the class just dynamically pulls in the id of the record your component is being viewed on! Super convenient! We are also able to call our apex method using the contactGrab({‘acctId’: this.recordId}) statement because we imported our apex class at the top of the LWC here “import contactGrab from “@salesforce/apex/ContactGrabber.getAllRelatedContacts”;”. That being said we haven’t looked at the apex code yet, so let’s check it out… there’s not much there but it’s still important.

public with sharing class ContactGrabber {
    @AuraEnabled
    public static List<Contact> getAllRelatedContacts(Id acctId){
        return [SELECT Id, FirstName, LastName FROM Contact WHERE AccountId = :acctId];
    }
}

The @AuraEnabled declaration allows us to import this method in our class to the LWC. It’s import to do that, so don’t forget!

Now that we have our contacts we actually need to generate the document. So let’s get to it bruh! The buildDocument method starts this process so let’s check it our first.

buildDocument(contactsPassed){
        let document = new docx.Document();
        let tableRows = [];
        tableRows.push(this.generateHeaderRow());

        contactsPassed.forEach(contact => {
            tableRows.push(this.generateRow(contact));
        });

        this.generateTable(document, tableRows);
        this.generateDownloadLink(document);
    }

In the code above we’re declaring a new docx Document object with the “new docx.Dcoument()” declaration. After this we create an array of table cells (because in this example we are building a table of contacts in a word document). We then proceed to push a table row into the table rows array by calling the generateHeaderRow method in our js controller. Let’s check out that class next.

generateHeaderRow(){
        let tableHeaderRow = new docx.TableRow({
            children:[
                new docx.TableCell({
                    children: [new docx.Paragraph("First Name")],
                    borders: this._no_border
                }),
                new docx.TableCell({
                    children: [new docx.Paragraph("Last Name")],
                    borders: this._no_border
                }) 
            ]
        });

        return tableHeaderRow;
    }

The generateHeaderRow method use the docx.TableRow object, the docx.TableCell object and the docx.Paragraph object to generate a table row with two cells. One cell for the contacts first name and another cell for a contacts last name. It then returns this table row.

Let’s get back to the buildDocument method now. The next thing that happens is we iterate through the list of contacts that we pulled from our apex controller and generate a table row for each contact by calling the generateRow method and push that into our tableRows array. So let’s look at the generateRow method next.

generateRow(contactPassed){
        let tableRow = new docx.TableRow({
            children: [
                new docx.TableCell({
                    children: [new docx.Paragraph({children: [this.generateTextRun(contactPassed["FirstName"].toString())]})],
                    borders: this._no_border
                }),
                new docx.TableCell({
                    children: [new docx.Paragraph({children: [this.generateTextRun(contactPassed["LastName"].toString())]})],
                    borders: this._no_border
                })
            ]
        });

        return tableRow;
    }

This code does something similar to the generateHeaderRow method, the only difference between the two is that I call the generateTextRun method instead of just outright declaring a new docx Paragraph object. The docx.TextRun object allows us to specify traits in our text. Things like font size, font type, whether the text is bold and a ton more. Let’s check out the generateTextRun method to see what it’s doing.

generateTextRun(cellString){
        let textRun = new docx.TextRun({text: cellString, bold: true, size: 48, font: "Calibri"});
        return textRun;
    }

In the method above we are generating what docxjs calls a text run and then returning it. It’s pretty simple as you can see. I’m just declaring the traits I want for my text. Nothing more, nothing less.

Back to the buildDocument method then! The next thing we do is call the generateTable method and pass is our docx.Document object along with our array of tableRows. Let’s check out that method next!

generateTable(documentPassed, tableCellsPassed){
        let docTable = new docx.Table({
            rows: tableCellsPassed
        });

        documentPassed.addSection({
            children: [docTable]
        });
    }

In this method we are creating a new docx.Table and assigning the array of rows we passed to this method to the rows parameter of the docx.Table. We then proceed to add a new section to our docx.Document and put the table in that section. This actually adds the table to the document we are creating.

Now, one last time, let’s check out the buildDocument method again. The last thing we do in it is call the generateDownloadLink method. So let’s take a look at that method now.

generateDownloadLink(documentPassed){
        docx.Packer.toBase64String(documentPassed).then(textBlob =>{
            this.downloadURL = 'data:application/vnd.openxmlformats-officedocument.wordprocessingml.document;base64,' + textBlob;
            this.template.querySelector(".slds-hide").classList.remove("slds-hide");
        });
    }

What this method does, is take the document we built and create a url that will allow us to download the word doc. It also turns on the download button in our LWC. We generate a base64 encoded string using the docx.Packer object and assign it to the downloadURL.

And believe it or not, that’s it! Yea!!! You’ve just figured out how to build your own LWC that can produce word documents. You can build off this base to do whatever you think you might wanna do. You could, with the help of other js libraries build a whole document templating app. I’ve done it in the past, it’s challenging, but doable! Good luck building whatever it is you’re building with this!


Get Coding With The Force Merch!!

We now have a redbubble store setup so you can buy cool Coding With The Force merchandise! Please check it out! Every purchase goes to supporting the blog and YouTube channel.

Get Shirts Here!
Get Cups, Artwork, Coffee Cups, Bags, Masks and more here!


Check Out More Coding With The Force Stuff!

If you liked this post make sure to follow us on all our social media outlets to stay as up to date as possible with everything!

Youtube
Patreon
Github
Facebook
Twitter
Instagram


Salesforce Development Books I Recommend

Advanced Apex Programming
Salesforce Lightning Platform Enterprise Architecture
Mastering Salesforce DevOps

Good Non-SF Specific Development Books:

Clean Code
Clean Architecture

Salesforce Admin Tutorial: How to create Confetti Celebrations and use the Trailshread Audio Player

Why would we create Celebrations or use the Trailshred Audio Player at all?

To be honest idk dawg, maybe just to spice up your life a little bit and have some fun? You could make a super sweet easter egg for your Salesforce org. Maybe you wanna boost your Sales teams morale with something interesting and unexpected? No matter how you slice this banana bread chocolate chip pancake it all boils down to choosing to do something that’s a little fun for the people around you and sometimes that’s the best thing you could build. Everybody gets tired of being a serious fanci boi all day. Take a stroll down having a little fun lane for once my guy.


How to setup Confetti Celebrations using Paths

To be honest, this is super easy. If you’ve never heard of paths, you can check out some sweet info here. Basically you just do the following:

1) Go to Setup -> Path Settings and click the “New Path” button

Path Settings

2) After clicking the “New Path” button follow the steps and fill out the fields as requested, until you get to Step 3.

3) On step 3 of the Path setup there will be an area called “Enable Celebrations”. Enable them. Then pick what triggers the confetti celebrations and how often the celebrations happen.

4) Congrats, you did it!


How to use the Trailshred Audio Player to play some ultra lit audio for your Sales Broz

And now we get to the guuuuuuddddddddddddd stuff. Salesforce has created a relatively simple and lightweight unmanaged package called the Trailshred Audio Player to allow you to play audio you upload to static resources by playing an LWC on lightning record pages. Let’s check out how to use this thing.

1) Install the unmanaged package here: https://login.salesforce.com/packagingSetupUI/ipLanding.app?apvId=04t1U000007sa55QAA

2) After the Trailshred Audio Player has been installed in your org, create and upload any audio file as a static resource (the audio must be less than 5mb and be an mp3 or wav file).

3) Copy the name of the static resource you just created.


4) Go to Setup -> Custom Metadata Types -> Trailshred Settings -> Manage Records

5) Create a new Trailshred Settings record and place the name of your static resource audio file in the “Audio Static Resource Path” field, then pick the Object you want the audio to run on, pick the field you want the audio to trigger on and the value for that field it should trigger on.

6) That’s it playur, you did it! On to the next section!


Setting up the Lightning App Record Page to Play the Celebration

Alright alright alright, we’re almost there, this is the last step and it’s super easy. You gotta create a lightning record page app. Let’s check out how to get it done son.

1) Go to Setup -> Lightning App Builder and click the “New” button to create a new lightning app record page (or choose to update an existing one).

2) Search for the “Path” component on the lightning app builder page and place it on the page. This will add your confetti celebration.

3) Search for the “Trailshred Audio Player” in the component search in the lightning app builder and place it at the bottom of the page. This component is invisible (because it just plays audio) so after placing it you should just see it represented by an empty space.

4) Save and Activate your lightning app record page.

5) That’s it! You did it homie! You finally had some fun!

That’s it guys, hopefully you had a little fun building it and someone gets a good laugh out of whatever you built!

Get Coding With The Force Merch!!

We now have a redbubble store setup so you can buy cool Coding With The Force merchandise! Please check it out! Every purchase goes to supporting the blog and YouTube channel.

Get Shirts Here!
Get Cups, Artwork, Coffee Cups, Bags, Masks and more here!

Check Out More Coding With The Force Stuff!

If you liked this post make sure to follow us on all our social media outlets to stay as up to date as possible with everything!

Youtube
Patreon
Github
Facebook
Twitter
Instagram


Salesforce Development Books I Recommend

Advanced Apex Programming
Salesforce Lightning Platform Enterprise Architecture
Mastering Salesforce DevOps

Good Non-SF Specific Development Books:

Clean Code
Clean Architecture

Salesforce Development Tutorial: How to use the Safe Navigation Operator in Apex to reduce the amount of null checking in your codebase

Why use the Safe Navigation Operator??

My guy, this is the best thing Salesforce has added to the Apex language in forever! Embrace it! To elaborate on that though, let me hit you with this thrilling sales pitch. Just imagine a late night commercial selling you garbage, but the garbage is actually good.

Are you frustrated with the insane amount of null checking you have to do when writing your apex code? Do you wish there was a way you didn’t have to do a null to prevent your code from crashing and burning? Well Salesforce has a solution to that problem! The safe navigation operator! Starting with the Winter 21 release your dreams have finally come true! Erase all those null checks you were doing on your soql queries, your objects and so much more! Watch 4+ lines of code get condensed to a single line and enjoy your life as a Salesforce Developer just a little bit more!

Ok… enough of that, hopefully that sweet action sales pitch sold you, but if it didn’t let’s check out some code to hopefully convince you the safe nav operator is worth your time.


Safe Navigation Operator Code Examples

Before we get started, if you’d prefer to check out these examples on GitHub, you can see them here. Otherwise, let’s keep on keepin on. Let’s start with a soql example that doesn’t use the safe navigation operator. In this example we just want to get the name of an Account.

public static void noSafeNav(){
        List<Account> acctList = [SELECT Id, Name FROM Account WHERE Name = 'Kevin' LIMIT 1];
        if(!acctList.isEmpty()){
            String acctName = acctList[0].Name;
        }
}

As you can see above, to navigate safely without the risk of our code crashing from a null pointer exception or a, “list has no rows to assign to SObject” exception we need 4 lines of code. Not bad, but after awhile that can get tedious. Now let’s try to do the same thing with the safe navigation operator.

public static void safeNav(){
        String acctName = [SELECT Id, Name FROM Account WHERE Name = 'Kevin' LIMIT 1]?.Name;
}

Oh dwamnnnnnnnnnnnnn, with the safe navigation operator we are able to do this in a single line of code… uhmazing. If you didn’t know the safe navigation operator is that question mark between the soql query and the .Name. Basically what the safe navigation operator does is check whether the query is null before trying to grab the name field from the SOQL query. If the query is null (or returns nothing), it will assign the value null to the acctName variable. This is super convenient and can reduce your codebase a ton.

Hopefully this example has convinced you it’s worth it to utilize the safe navigation operator but if it hasn’t there is a mapping example in the github repo too. It can also save you a ton of null checking with maps as well!


Get Coding With The Force Merch!!

We now have a redbubble store setup so you can buy cool Coding With The Force merchandise! Please check it out! Every purchase goes to supporting the blog and YouTube channel.

Get Shirts Here!
Get Cups, Artwork, Coffee Cups, Bags, Masks and more here!


Check Out More Coding With The Force Stuff!

If you liked this post make sure to follow us on all our social media outlets to stay as up to date as possible with everything!

Youtube
Patreon
Github
Facebook
Twitter
Instagram


Salesforce Development Books I Recommend

Advanced Apex Programming
Salesforce Lightning Platform Enterprise Architecture
Mastering Salesforce DevOps

Good Non-SF Specific Development Books:

Clean Code
Clean Architecture