You are on page 1of 91

Build Applications Programmatically

on the Salesforce Platform (DEX450)


Exercise Guide (Winter 22 Release)
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

Table of Contents
1-1: Explore the Certification App (Instructor Demo) 4
1-2: Prepare Your Training Org and Environment 6
1-3: Create a Sandbox 10
3-1: See Apex in Action 11
3-2: Create and Use an Apex Class 14
3-3: Take a Quick Tour of Apex 16
3-4: Examine Implicit Operations 21
3-5: Profile Limits Using the Developer Console 23
3-6: Work with a Custom Object 24
4-1: Create and Run a Query in the Developer Console 25
4-2: Write a SOQL Query that Uses a WHERE Clause in VS Code 27
4-3: Write and Execute a SOQL Query in Apex 29
4-4: Write a Dynamic Query in Apex 30
4-5: Write and Test Child-to-Parent Relationship Queries 32
4-6: Write and Test Parent-to-Child Relationship Queries 33
4-7: Create a Simple SOSL Search 34
5-1: Execute DML Commands 36
5-2: Handle DML Errors and Exceptions 38
6-1: Deploy Code from Sandbox to Production (Optional) 39
7-1: Define a Trigger 42
7-2: Define the Trigger's Business Logic 43
8-1: Define an Apex Class 45
9-1: Explore the Implicit Firing of Triggers 46
9-2: View the Events that Occur During a Rollback 48
9-3: Use a Platform Event for Immediate Error Logging 50
10-1: Make Test Data Available to Test Methods 52
10-2: Write and Run an Apex Test 54
11-1: Refactor a Trigger to Avoid SOQL Limits 56
11-2: Refactor a Trigger to Avoid DML Limits 58
12-1: Create a Formula Field to Eliminate a Query 59
12-2: Create Fields for Counting Certification Elements 60
12-3: Create Collections to Filter the Query 62

©Copyright 2021 salesforce.com, inc. All rights reserved. 2


Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

12-4: Use a Map to Aggregate Results 64


12-5: Create Certification Held Records 66
12-6: Use a Workflow to Avoid Creation of Duplicate Records (Optional) 68
13-1: Create a Simple Visualforce Page 71
13-2: Create a Simple Technician Status Page 74
13-3: Reference a Controller Extension in a Visualforce Page 77
13-4: Creating a Read/Write Property in a Custom Controller 79
13-5: Redirecting to a Results Page 81
13-6: Create a Page to Display a List of Records 83
13-7: Create a Simple Search Page 84
14-1: Defend Against SOQL Injection 85
14-2: Write a Test Class for SearchCoursesPage 87
15-1: Create and Surface an Aura Component (Optional) 88
15-2: Create and Surface a Lightning Web Component (Optional) 90

©Copyright 2021 salesforce.com, inc. All rights reserved. 3


Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

1-1: Explore the Certification App (Instructor Demo)

Goal:
Familiarize yourself with the custom Certification app.

Tasks:
1. Locate the correct Service Vendor account.
2. Create a new technician record.
3. Sign your new technician up for training.
4. Add a certification attempt for your technician.
5. Document that your technician has earned the certification.
6. Discussion.

Time:
5 minutes

Instructions:

1. Locate the correct Service Vendor account.

A. In the Certification app, open the record detail page for the Windy City Network
Solutions Account. Its record type is Service Vendor.

2. Create a new technician record.

A. Create a related Contact as follows:


Account Windy City Network Solutions
Record Type Technician
First Name Jonas
Last Name Whittier

3. Sign your new technician up for training.

A. Open the record detail page for the [101] AWCA Server course.
B. Open its related delivery DELIVERY-00034.
C. Create a related Course Attendee as follows:
Student Jonas Whittier
Course Delivery DELIVERY-00034
Status Enrolled

4. Add a certification attempt for your technician.

©Copyright 2021 salesforce.com, inc. All rights reserved. 4


Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

A. Open the Contact detail page for Jonas Whittier.


B. Create a related Certification Attempt as follows:
Record Type Multiple Choice
Certification Element AWCA Server Multiple Choice
Certification Candidate Jonas Whittier
Attempt Date (Enter Today's Date)
Status Complete/Pass

5. Add a Certification Held record for your technician.

A. Open the Certification Element detail page for the AWCA Server Multiple Choice
certification attempt you just created, and then open the AWCA Server Certification
record.
B. Create a related Certification Held as follows:
Certification AWCA Server
Certified Professional Jonas Whittier
Date Achieved (Enter Today's Date)

6. Discussion

A. Which step(s) in this process would benefit from automation?

©Copyright 2021 salesforce.com, inc. All rights reserved. 5


Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

1-2: Prepare Your Training Org and Environment

Goal:
Prepare your org for classroom activities and access after class.

Tasks:
1. Update your user details in your training org.
2. Download your lab files from the Files tab.
3. Turn off Browser Caching.
4. Open the Project in VS Code.
5. Authorize the org using the Salesforce CLI.
6. Retrieve the Base metadata.
7. Update VS Code Settings.
8. Refresh SObject Definitions
9. (Optional) Enable Apex Code Formatting

Time:
60 minutes

Instructions:

1. Update your user details in your training org.

A. Update and save your Advanced User Details as follows:


First Name (your first name)
Last Name (your last name)
Email (an email you can access from class)
Development Mode Select
Show View State in Select
Development Mode

©Copyright 2021 salesforce.com, inc. All rights reserved. 6


Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

2. Download your lab files from the Files tab.

A. Navigate to the Files tab.


B. Download DEX450_SFDX_Exercises and unzip it on your Desktop.

Note: If you are using a Windows machine and your system administrator disabled compressed
folders, you may need to download third-party unzipping software such as 7-zip.

3. Turn off Browser Caching.

A. In Setup, go to Security | Session Settings.


B. Locate the Caching section. You may need to scroll upwards to find it.
C. Uncheck the box next to Enable secure and persistent browser caching to improve
performance. Turning off this setting is useful when working on Lightning components.

4. Open the Project in VS Code.

A. Open VS Code.
B. Open the folder selection dialog as follows, depending on your operating system:
Windows: File | Open Folder
Mac: File | Open.

C. Inside of the folder selection dialog, navigate to the DEX450_SFDX_Exercises


directory and click the following:
Windows: Select Folder
Mac: Open

5. Authorize the org using the Salesforce CLI.

A. Open the Terminal window (View | Terminal).


B. Run the following command:
sfdx auth:web:login -a DEX450 -s

Note: The -a flag sets the alias of the org to DEX450. The –s flag sets it as the default org.

C. In a few seconds, your default browser will open in a screen to log into Salesforce. Use
the credentials your instructor gave you.
D. Click Allow.

©Copyright 2021 salesforce.com, inc. All rights reserved. 7


Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

E. If you received an error related to port 1717, you may need to kill a process.
Windows: Ctrl+Alt+Delete -> Task Manager -> End process named Node.
(Node.js developers might have several running processes with this name)
Mac: lsof -i tcp:1717 and then kill -9 <the process ID>

6. Retrieve the Base metadata.

A. In VS Code, open manifest/package.xml and observe the use of the wildcard


character * as well as individually listed elements. Not all Metadata types support the
wildcard. You can find out which do in the Metadata API Developer Guide.
B. Right-click the manifest/package.xml in the sidebar and select the option SFDX:
Retrieve Source in Manifest from Org. This will populate the force-app/
main/default folder.

Note: If you do not see the Retrieve Source command when you right click package.xml, make sure
that you have installed the Salesforce Extension Pack in VS Code.

7. Update VS Code Settings.

A. From the Command Palette (View | Command Palette) enter the following:
> Preferences: Open Workspace Settings

B. In the Search Settings box, type deploy and enable Push-or-deploy-on-save.


C. In the Search Settings box, type coverage and enable Retrieve-test-code-coverage.
D. In the Search Settings box, type sobject refresh and enable Enable-sobject-
refresh-on-startup.

Note: We set these options in your Workspace settings to avoid impacting any of your other projects.
You may wish to enable some or all of them in your User Settings instead.

8. Refresh SObject Definitions

A. From the Command Palette, run the following to enhance VS Code's autocomplete
abilities.
> SFDX: Refresh SObject Definitions

B. Select All SObjects.

©Copyright 2021 salesforce.com, inc. All rights reserved. 8


Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

9. (Optional) Enable Apex Code Formatting

A. Install the LTS (Long Term Support) version of NodeJS from nodejs.org.
B. Use the VS Code Extensions Marketplace to install the Prettier - Code formatter
extension. There are many extensions with the word Prettier in the title. Make sure to
download the one titled Prettier - Code formatter which has millions of installs.
C. From a Terminal (View | Terminal) in VS Code, run the following command:
npm install
D. Restart VS Code.
E. In VS Code, open
force-app/main/default/classes/CourseAttendeeTriggerHandler.cls.
F. From the Command Palette (View | Command Palette) enter the following to format
the class:
> Format Document

G. Consider enabling the Editor: Format on Save option in your Workspace Settings.

Note: We have provided a sample .prettierrc file at the root of the project. You can customize
this file to your liking to configure Prettier.

1-3: Create a Sandbox

Goal:
Create a sandbox to configure and test changes separate from the production environment.

Tasks:
1. Create a developer sandbox.

Time:
5 minutes

Instructions:

1. Create a developer sandbox named dev.

A. In your web browser, go to Setup in your org and navigate to Environments |


Sandboxes.

©Copyright 2021 salesforce.com, inc. All rights reserved. 9


Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

B. Create a new sandbox according to the following:


dev<xxxxx><yy>
Name
where <xxxxx> is the integer number in your username
and <yy> are your initials - so for example dev12345ab
Description This is a development environment.
Type Developer

©Copyright 2021 salesforce.com, inc. All rights reserved.


10
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

3-1: See Apex in Action

Goal:
Execute Apex to create a new Contact record in the database.

Tasks:
1. Configure the Debug Logs using Developer Console.
2. Review the User Trace Flags.
3. Open the Execute Anonymous window.
4. Enter the code to execute.
5. Examine the logs.
6. Examine the result in the user interface.

Time:
15 minutes

Instructions:

1. Configure the Debug Logs using Developer Console.

A. Open Developer Console.


B. Click Debug, then click Change Log Levels.
C. Under General Trace Settings for You, observe a row with these values:
LogType DEVELOPER_LOG
DebugLevel SFDC_DevConsole
D. Click Add/Change in that row to open a window that allows you to change the
granularity of different types of messages.
E. Set the DB, Apex Code and Profiling entries to Finest and System to Fine.
F. Click Done, and then click Done again.

2. Review the User Trace Flags.

A. Leave Developer Console open. You'll be coming back shortly.


B. In Setup, navigate to Environments | Logs | Debug Logs.
C. Observe the presence of a User Trace Flag and answer the following questions.
i. Who is it assigned to?

©Copyright 2021 salesforce.com, inc. All rights reserved.


11
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

ii. Who requested it?


iii. What is the LogType?
iv. What caused it to be created?
v. When will it end?

3. Open the Execute Anonymous window.

A. Return to Developer Console.


B. Click Debug | Open Execute Anonymous Window.
C. If there is any code in the Enter Apex Code window, remove it.
D. Select Open Log in the bottom right-hand corner.
E. If you wish, you can expand the window by clicking the Up arrow in the top right corner.

4. Enter the code to execute.

A. In VS Code, open Contact_EA.apex.

Note: Unless otherwise specified, look in EXFiles\Current-Exercise-Number\ when told to


open a file. In this example, the full path is in EXFiles\3-1\Contact_EA.apex. You can also
easily locate a file in VS Code by using the Ctrl + P (or Cmd + P) shortcut which opens a
filename search tool.

B. Copy the contents of the file to the clipboard.


C. Return to the Salesforce UI in your web browser and paste the copied code into the
Execute Anonymous window in Developer Console.
D. Click Execute in the bottom right-hand corner. The code will run and a tab will open
with the log containing the results of the operation.

©Copyright 2021 salesforce.com, inc. All rights reserved.


12
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

5. Examine the logs in Developer Console.

A. Click the Debug Only checkbox to filter the log and only display our debug statements.
The window will display a log entry with the ID of the inserted record.
B. Deselect Debug Only. The full log view will display again.
C. Enter DML into the Filter input box (case-sensitive).
D. Notice the limits usage for DML Statements and DML Rows.
E. Select File | Close All to close the log. If you don't do this, the same log will be open
the next time that you open Developer Console.
F. Close Developer console.

6. Examine the result in the Salesforce user interface.

A. In the Salesforce UI, confirm that June Morgan, the record inserted using Apex,
appears in the Recent Contacts section.

Question: what would happen if you tried to insert a Contact named June Morgan again?

©Copyright 2021 salesforce.com, inc. All rights reserved.


13
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

3-2: Create and Use an Apex Class

Goal:
Create an Apex class named ContactManager and define a method within the class to create a
Contact record in the database.

Tasks:
1. Create an Apex class.
2. Invoke the class method using Execute Anonymous.
3. Examine the output to see the invocation of the class.

Time:
10 minutes

Instructions:

1. Create an Apex class.

Tip: Consult your cheat sheet as needed for instructions to perform common tasks like creating an
Apex Class.

A. In VS Code, create a new Apex class ContactManager, overwriting all of its contents
with ContactManagerClass.txt from the appropriate EXFiles folder.
B. Save ContactManager.cls. Because you enabled the deploy on save option in VS
Code, you should see something similar to this in the output pane (View | Output):

Note: Throughout the instructions we assume you have enabled deploy on save. If you decide not to
enable that option, you will need to manually deploy files after saving them.

©Copyright 2021 salesforce.com, inc. All rights reserved.


14
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

2. Invoke the class method using Execute Anonymous.

A. In VS Code, open ContactManager_EA.apex from the appropriate EXFiles folder.


B. Make sure that no text is selected in VS Code, and then use the Command Palette to
run the following:
> SFDX: Execute Anonymous Apex with Editor Contents

3. Examine the output to see the invocation of the class.

A. In the Output tab (View | Output) search for the string USER_DEBUG and locate the two
debug statements. You can search either by going to Edit | Find or by using the
keyboard shortcut Ctrl + F. Note: Be sure the Salesforce CLI Is chosen from the
dropdown Menu.
B. Notice that the newly created record has an ID, which was returned by the method.
C. Search the output for the string ContactManager and observe the invocation of the
static addContact() method.

Note: This isn't the only way to see log info in VS Code. You'll learn more about logs later.

©Copyright 2021 salesforce.com, inc. All rights reserved.


15
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

3-3: Take a Quick Tour of Apex

Goal:
Quickly learn some Apex fundamentals that will be familiar to you, and check out some simple
differences.

Tasks:
1. Enable Replay Debugger.
2. Set up the main class.
3. Set up and review the test class.
4. Run the test.
5. View code coverage.
6. Replay the code.
7. Use a Checkpoint.

Time:
45 minutes

Instructions:

1. Enable Replay Debugger.

A. In VS Code, run the following from the Command Palette:


> SFDX: Turn on Apex Debug Log for Replay Debugger

In the VS Code status bar (bottom of the window) you should see "Recording detailed logs
until [30 minutes from now] "

If this command fails to run with the following error:

"FIELD_INTEGRITY_EXCEPTION: This entity is already being traced by a trace flag with a start and
expiration date that overlap this trace flag's start and expiration date."

then in your org close the Developer Console (if open), navigate to the Debug Logs page in Setup
and delete the SFDC_DevConsole user trace flag. Re-run the command.

2. Set up the main class.

©Copyright 2021 salesforce.com, inc. All rights reserved.


16
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

A. In VS Code, create a new Apex class CourseManager, overwriting all of its contents
with CourseManagerClass.txt.
B. Complete the TODOs.

3. Set up and review the test class.

A. In VS Code, create an Apex class named CourseManager_Test, overwriting all of its


contents with CourseManager_Test.txt.
B. Note the following in the code:

i. The following two lines of code create two lists of records. There will be 3
overlapping records with names: course3, course4, and course5.
List<Course__c> oldCourses = createTestDataCourses(0, 5);

List<Course__c> newCourses = createTestDataCourses(3, 6);

ii. The following line checks whether the code that will be moved to production actually
fulfills the business requirement. If the assertion fails, an exception will be caused,
which will fail the test.
System.assert(duplicateCourses.size()==3);

4. Run the test.

A. Make sure that the Output Pane is visible. (View | Output)


B. Click the Clear Output icon next to the output selection dropdown.
C. Open the Test View by running the following Command Palette command:
> Test: Focus on Apex Tests View

Note: If you do not see your test listed, move your mouse over the words "APEX TESTS" and click
the Refresh Tests button (a circular arrow).

D. In the list of Apex Tests, click CourseManager_Test.


E. Click the green arrow on the same line as CourseManager_Test to run the test.
F. The circle should turn green, indicating the test passed.
G. Scroll to the bottom of the Output pane and look at the Test Summary section that
includes (among many others) the following name/value pairs:

©Copyright 2021 salesforce.com, inc. All rights reserved.


17
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

Outcome Passed
Tests Ran 1

5. View code coverage.

A. In VS Code, return to CourseManager.cls.


B. Click the Highlight Apex Code Coverage button in the VS Code Status bar.
C. All lines should be highlighted in green, indicating that they are covered.
D. Click the Highlight Apex Code Coverage button again to turn off highlighting.

Note: If you receive a message that "No code coverage information was found for this file", enable
the Retrieve-test-code-coverage option as instructed in Exercise 1-2.

6. Replay the code.

A. In VS Code, add a breakpoint to the following line of CourseManager.cls.


Remember, you've got a cheat sheet to help!
Set<Course__c> courseDuplicatesSet = new Set<Course__c>();

B. Run the following from the Command Palette:


> SFDX: Get Apex Debug Logs

C. A list of one or more logs will display. Select the most recent log and it will download
and open in its own editor tab.
D. Go to View | Run to change the selected area in the sidebar.
E. Right-click anywhere inside of the log file and select the following option:
SFDX: Launch Apex Replay Debugger with Current File

F. Press F5 (or the Continue icon in Debugger tools) and it will stop at your breakpoint.
G. Observe that a string representation of newCourseList is visible as a local variable in
the sidebar. oldCourseList says List of size 6 too large to display.
H. Press F10 (or the Step Over icon in Debugger tools).
I. Expand the variable newCourse in the sidebar.
J. Press F10 repeatedly, watching the value of newCourse change, until you reach the
return statement.

©Copyright 2021 salesforce.com, inc. All rights reserved.


18
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

K. A known limitation of Replay Debugger is that modifying a collection does not update
the collection variable in the sidebar when using standard breakpoints. Thus, the value
of courseDuplicatesSet will not be reflected.
L. Press Shift + F11 (or the Step Out icon in Debugger tools) when you reach the
return statement. You will return to the testFindDuplicates method in the test
class.
M. Observe the value of duplicateCourses.
N. Press F5 (or the Continue icon in Debugger tools) and your replay session will end.

7. Use a Checkpoint

A. In VS Code, place your cursor on the following line of CourseManager.cls:

return courseDuplicatesSet;

B. Run the following from the Command Palette to add a checkpoint to the line:
> SFDX: Toggle Checkpoint

C. Run the following from the Command Palette to ensure that a heap dump is collected
on the server when this checkpoint is reached:
> SFDX: Update Checkpoints in Org

D. Use the Apex Tests view in VS Code to execute the CourseManager_Test test again.
E. Use the Get Apex Debug Logs command again to download the Apex log you just
generated by running the test. The log's contents should automatically open in a VS
Code editor window.
F. In the newly opened VS Code editor window, search the log contents for the phrase
HEAP_DUMP to ensure the checkpoint functioned as expected.
G. Launch the Replay Debugger again, selecting the new log file.
H. Press the Continue button in the debugger tools until you reach the checkpoint that you
placed on the return statement.
I. Observe that the value of courseDuplicatesSet can now be observed because
we're using a checkpoint rather than a breakpoint.

©Copyright 2021 salesforce.com, inc. All rights reserved.


19
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

J. Observe that the value of oldCourseList, which was previously too large to display,
can also now be observed. This is another example of a checkpoint making more
information available.
K. Run the SFDX: Toggle Checkpoint and SFDX: Update Checkpoints in Org
commands again to remove the checkpoint.
L. Run the following from the Command:
> SFDX: Turn Off Apex Debug Log for Replay Debugger

Tip: Checkpoints expire after 30 minutes and heap dumps expire after a day.

©Copyright 2021 salesforce.com, inc. All rights reserved.


20
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

3-4: Examine Implicit Operations

Goal:
Examine the operations implicitly occurring when you perform a DML operation.

Tasks:
1. Ensure a trace flag is running.
2. Create a Course Attendee record in the user interface.
3. View the logs to see operations implicitly invoked due to the DML operation.

Time:
10 minutes

Instructions:

1. Ensure a trace flag is running.

A. Open Developer Console so that an active trace flag with Debug Level
SFDC_DevConsole is running. Keep it open until you complete Exercise 3-6.

Note: By default, the trace flags generated for Replay Debugger logs do not have Profiling FINEST
which is required for this specific log.

2. Create a Course Attendee record in the user interface.

A. Open the detail page for the Course Delivery record named DELIVERY-00025.
B. Create a related Course Attendee as follows:
Course Delivery DELIVERY-00025
Student Clara Petit
Status Enrolled

3. View the logs to see operations implicitly invoked due to the DML operation.

A. In VS Code, run the following from the Command Palette:


> SFDX: Get Apex Debug Logs

B. A list of one or more logs will display. Select the most recent log and it will download
and open in its own editor tab.

©Copyright 2021 salesforce.com, inc. All rights reserved.


21
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

C. Search the log file you just downloaded for the string AfterInsert. There should be
two results. What do the lines containing this phrase indicate?
D. Confirm that the provideAccessLMS method of the
CourseAttendeeTriggerHandler class was executed.
E. Search the log for the string WF and verify that the New Course Delivery Created
workflow rule is mentioned in the logs. It fires because a Roll Up Summary field exists
on Course Delivery that counts the number of attendees.
F. On the line that says WF_CRITERIA_BEGIN, observe that the end of the line says
ON_CREATE_ONLY|0, indicating that the Workflow rule did not meet the evaluation
criteria and thus did not execute.

Note: Even if the DML operation on an object does not meet a Workflow Rule's evaluation criteria,
you will still see a log entry that says WF_RULE_EVAL_BEGIN, but you will shortly after see
WF_RULE_NOT_EVALUATED to indicate that the Evaluation Criteria were not met.

3-5: Profile Limits Using the Developer Console

Goal:
Investigate limits using the Developer Console.

Tasks:
1. Review the limit profiling information in the log.

Time:
5 minutes

Instructions

1. Review the limit profiling information in the log.

A. Open Developer Console if it is not already open.


B. Click Debug, then deselect Show My Current Logs Only.
C. Click the Logs tab in the bottom panel and double-click on the most recent entry.
D. Click Debug | Switch Perspective | All (Predefined).
E. In the Execution Overview panel, notice the Save Order of the various operations.

©Copyright 2021 salesforce.com, inc. All rights reserved.


22
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

F. Click the Timeline tab in the Execution Overview panel. Notice the entries in the
Category, Millis, and % columns.
G. Switch to the Limits tab in the Execution Overview panel. Enter STATEMENT in the
Filter input box of the Execution Log panel (case-sensitive).
H. Click the first entry in the Execution Log panel. This resets the Used so far column in
the Limits tab. The Source panel jumps to the line of code that was executed at that
point in time.
I. Click the third-to-last entry in the Execution Log panel. The values for SOQL and
SOQL_ROWS Limits Used so far are updated. The Source panel jumps to the line of
code that was executed at that point in time.
J. Click the last entry in the Execution Log panel. All limits used now display.

©Copyright 2021 salesforce.com, inc. All rights reserved.


23
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

3-6: Work with a Custom Object

Goal:
Work with the fields of the Course object.

Tasks:
1. Write code to insert a record for the Course object.
2. Check the Salesforce UI to ensure that the record was inserted successfully.

Time:
15 minutes

Instructions:

1. Write code to insert a record for the Course object.

A. In VS Code, open CreateCustomObjRecord_EA.apex.

NOTE: Remember that you can use Ctrl + P (or Cmd + P) to easily find a file. Make sure to
pay attention to whether you're opening a file from EXFiles or EXFiles_solutions.

B. Complete the TODOs.


C. Execute the Apex from VS Code.

2. Check the Salesforce UI to ensure that the record was inserted successfully.

A. Locate the new Course named [104] Introduction to Programming.

©Copyright 2021 salesforce.com, inc. All rights reserved.


24
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

4-1: Create and Run a Query in the Developer Console

Goal:
Retrieve Cases using the Query Editor in the Developer Console.

Tasks:
1. Run a query in the Query Editor in the Developer Console.
2. Explore row-level options.
3. Delete Debug Logs.

Time:
5 minutes

Instructions:

1. Run a query in the Query Editor in the Developer Console.

A. Open Developer Console.


B. Open the Case object in the Object Inspector for reference.

i. Click File | Open.


ii. Select Objects as the Entity Type, type Case into the filter, then double-click the
entity Case. As a result, you should see a list of the Case's fields and their data
types.
iii. Click the Name header to sort the fields by name.

C. Create a query.

i. Holding the CTRL key, select the following fields from the Case.obj tab:
CaseNumber IsClosed
ClosedDate Status
Id Subject
ii. Click Query at the bottom of the list. The focus will shift to the Query Editor tab in
the bottom panel.

D. Run the query.

i. Ensure the Use Tooling API checkbox is not selected.


ii. Click Execute. As a result, a Query Results tab opens.

©Copyright 2021 salesforce.com, inc. All rights reserved.


25
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

2. Explore row-level options.

A. Select a single Case in the Query Results tab.


B. Click Open Detail Page. The selected case’s detail page should appear.
C. Notice other actions available from the Query Results tab, such as creating, deleting,
and updating sObject records.

3. Delete Debug Logs

A. From the Query Editor tab, run the following SOQL query.
SELECT Id, StartTime, LogUserId, LogLength, Location FROM ApexLog

B. Highlight one or more rows and click Delete Row.

Note: System debug logs such as those generated from Developer Console are retained for 24
hours. Monitoring debug logs are retained for seven days. You do not have to manually delete
logs, but if your org accumulates more than 1,000 MB of debug logs, users are prevented from
adding or editing trace flags. That is a scenario where you may wish to manually delete the logs
as you just did.

©Copyright 2021 salesforce.com, inc. All rights reserved.


26
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

4-2: Write a SOQL Query that Uses a WHERE Clause in VS Code

Goal:
Retrieve Cases that meet specific criteria.

Tasks:
1. Write and test queries with various WHERE clauses using the SOQL Builder extension in
VS Code.

Time:
20 minutes

Instructions:

1. Write and test a query using the SOQL Builder extension in VS Code.

A. In VS Code open the Command Palette and run the following:


> SFDX: Create Query in SOQL Builder

B. Create a query that selects the Id, Subject, Status and IsClosed fields from the Case
sObject retrieving only "Closed" records.
C. Save your query as a file called Task1.soql in the /scripts/soql folder.

2. Repeat step 1 for the following queries:

A. Create a query that selects the Id, Subject and Type fields from the Case sObject
retrieving only records that have no specified type (Type is a nullable field so a Case
without a type has a Null value). Save your query in a file called Task2.soql.
B. Create a query that selects the Id, Subject, Priority and Product_Category__c fields
from the Case sObject retrieving only "Printers" product category records that have a
"High" priority. Save your query in a file called Task3.soql.
C. Create a query that selects the Id and Subject fields from the Case sObject retrieving
only records that have the word "printers" somewhere in the subject. Save your query in
a file called Task4.soql.
Note: If you wish to re-run any of your saved queries using SOQL Builder open the soql file and click
the Switch Between SOQL Builder and Text Editor icon (top right):

©Copyright 2021 salesforce.com, inc. All rights reserved.


27
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

Alternatively if you wish to remain in the text editor and run your query then simply highlight the
entire SOQL query before opening the Command Palette, and then run the following:
> SFDX: Execute SOQL Query with Currently Selected Text
Select REST API rather than Tooling API. The query result will be visible in the Output pane.

©Copyright 2021 salesforce.com, inc. All rights reserved.


28
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

4-3: Write and Execute a SOQL Query in Apex

Goal:
Print cases into the debug log.

Tasks:
1. Print a single case into the debug log.
2. Print multiple cases into the debug log.

Time:
10 minutes

Instructions:

1. Retrieve a single case.

A. In VS Code, open SOQLQueriesInApex-task1.apex.


B. Complete the TODOs to retrieve a single case and output the case details.
C. Click the Clear Output icon to clear the contents of the Output pane.
D. Execute the Apex from VS Code.
E. Search for the string USER_DEBUG to find your debug statements. A bit later, we'll show
you how to tail the logs and filter for this string automatically.

2. Retrieve multiple cases.

A. In VS Code, open SOQLQueriesInApex-task2.apex.


B. Complete the TODOs to retrieve multiple cases and execute a loop to output them one
by one.
C. Execute the Apex from VS Code and view the results in the Output pane.

©Copyright 2021 salesforce.com, inc. All rights reserved.


29
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

4-4: Write a Dynamic Query in Apex

Goal:
Retrieve cases that meet criteria specified at run time.

Tasks:
1. Use a bound variable to specify filter criteria.
2. Use Database.query() to work around the problem from Task 1.
3. (Optional) Use a bound variable to query by record type.

Time:
10 minutes

Instructions:

1. Use a bound variable to specify filter criteria.

A. Navigate to developer.salesforce.com and search for SOQL and SOSL Reference and
select it. Within that document search for Date Formats and Date Literals to
bring up an article with that name, and within that article, find the reference to
LAST_N_DAYS to see how it can be used in filter criteria for date values.
B. In VS Code, open SOQLDynamicQueryInApex-task1.apex and attempt to execute
the Apex. Observe that it returns an error because the bind variable is not supported
with LAST_N_DAYS in a bracketed SOQL query.

2. Use Database.query() to work around the problem from Task 1.

A. In VS Code, open SOQLDynamicQueryInApex-task2.apex.


B. Complete the TODOs.
C. Run the Apex and observe that it works.
D. Compare the Task 2 code to the Task 1 code. Can you explain why the code in Task 2
works but the code in Task 1 does not?

©Copyright 2021 salesforce.com, inc. All rights reserved.


30
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

3. (Optional) Use a bound variable to query by record type.

A. In VS Code, open SOQLDynamicQueryInApex-task3.apex.


B. Complete the TODOs.
C. Observe the use of the Schema class to retrieve the RecordTypeId prior to using it in
the WHERE clause of a SOQL query.
D. Run the Apex and view the results in the Output pane.

©Copyright 2021 salesforce.com, inc. All rights reserved.


31
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

4-5: Write and Test Child-to-Parent Relationship Queries

Goal:
Write child-to-parent relationship queries that explore relationships among sObjects in the
Certification application.

Tasks:
1. Select all Contacts and their related Accounts.
2. Move the query into Apex and output the results using a SOQL for Loop.
3. Select Courses that have related Certifications.

Time:
20 minutes

Instructions:

HINT: If needed, use Object Inspector in Developer Console to view field API names.

1. Select all Contacts and their related Accounts.

A. In VS Code, open SOQL-C2P-task1.soql and complete the task. You will write and
execute a SOQL query within VS Code.

2. Move the query into Apex and output the results using a SOQL for Loop.

A. In VS Code, open SOQL-C2P-task2.apex.


B. Complete the TODOs and run the Apex. If needed, search the Apex Developer Guide
for SOQL For Loops for assistance.

3. Select Courses that have related Certifications.

A. In VS Code, open SOQL-C2P-task3.soq and complete the task. You will write and
execute a SOQL query within VS Code.

©Copyright 2021 salesforce.com, inc. All rights reserved.


32
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

4-6: Write and Test Parent-to-Child Relationship Queries

Goal:
Write parent-to-child relationship queries that explore relationships among sObjects in the
Certification application.

Tasks:
1. Select all Accounts and their related Contacts.
2. Select all Certifications that have a related Course.

Time:
10 minutes

Instructions:

NOTE: You can choose whether to run the SOQL queries for this exercise in VS Code or in the
Developer Console Query Editor – whichever you prefer.

1. Select all Accounts and their related Contacts.

A. In VS Code, open SOQL-P2C-task1.soql and complete the task. You will write and
execute a SOQL query within VS Code.

2. Select all Certifications that have a related Course.

A. In VS Code, open SOQL-P2C-task2.soql and complete the task. You will write and
execute a SOQL query within VS Code.

©Copyright 2021 salesforce.com, inc. All rights reserved.


33
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

4-7: Create a Simple SOSL Search

Goal:
Search for text across multiple sObjects.

Tasks:
1. Construct a simple SOSL search.
2. Create a code block to cycle through the results.

Time:
15 minutes

Instructions:

1. Construct a simple SOSL search.

A. Open Developer Console. We must use Developer Console for this exercise because
unlike SOQL, SOSL cannot be executed directly from the Salesforce CLI.
B. In the Query Editor tab, write and execute a SOSL search for a person named Frank.
This search should be made on the Contact and User objects, returning the found
person’s FirstName and LastName.

Note: The search string must be delimited by curly braces without any quotes in the Query Editor tab.
However, single quotes are required in an Anonymous block.

2. Create a code block to cycle through the results.

A. In VS Code, open ParseSOSLSearch.apex and complete the TODOs.


B. From a Terminal in VS Code, execute the following command to prepare to stream the
logs. The terminal will not do anything immediately:
sfdx force:apex:log:tail -c

©Copyright 2021 salesforce.com, inc. All rights reserved.


34
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

C. In VS Code, run the Apex in ParseSOSLSearch.apex.


D. In the VS Code Terminal, view the log information that has been streamed and observe
the use of color to highlight important lines.
E. Stop tailing the logs using your choice of the following techniques:
i. Type Ctrl + C to keep the instance running while halting the command.
ii. Press the trashcan to kill the current terminal instance.

Tip: VS code allows you to maintain multiple terminal instances. If you only have one instance
running, killing it will close the Terminal panel. If you have multiple instances running, killing one
will automatically cause the panel to change to another instance.

F. Repeat steps B-E, but modify the tail command to filter for debug statements.
Windows CMD: sfdx force:apex:log:tail | findstr USER_DEBUG
Powershell: sfdx force:apex:log:tail | Select-String USER_DEBUG
Mac / Linux: sfdx force:apex:log:tail | grep USER_DEBUG

©Copyright 2021 salesforce.com, inc. All rights reserved.


35
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

5-1: Execute DML Commands

Goal:
Create and save Contacts.

Note: This exercise should be performed in the Sandbox if available. If your Sandbox is not yet available
then perform this exercise in your production org.

Tasks:

1. Write Apex code to insert Contacts using a standalone insert statement.


2. Write Apex code to insert Contacts using a Database class method.
3. Test your code.

Time:
25 minutes

Instructions:

1. Log into the Sandbox if available. If your Sandbox is not yet available then skip this step.

A. In Setup, navigate to Environments | Sandboxes.


B. Click Log In next to Dev.

iv. Username: (This field auto-populates)

NOTE: If Username does not auto-populate, enter


<prod username>.<sandbox name>
Example: admin@dex450.#####.com.dev#######

v. Password: (Same as production password)

It is usually a good idea to close any tabs you have open that reference your production
environment to avoid confusion.

2. Write Apex code to insert Contacts using a standalone insert statement.

A. In the Developer Console, create a new Apex class ContactsDML, overwriting its
contents with ContactsDML.txt.

©Copyright 2021 salesforce.com, inc. All rights reserved.


36
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

B. Complete the TODOs for Task 1, the standaloneDML method.

3. Write Apex code to insert Contacts using a Database class method.

A. Complete the TODOs for Task 2, the databaseMethodDML method.


B. Complete the TODOs for Task 3, the databaseMethodPartialCommit method.

4. Test your code.

A. Create another Apex Class ContactsDML_Test and overwrite its contents with
ContactsDMLTest.txt.
B. Complete the TODOs.
C. Click Run Test in the top right corner.
D. Click the Tests tab in the bottom panel.
E. Expand the collapsed folder by clicking on +.
F. Ensure that all your methods executed successfully. A green tick indicates success.

©Copyright 2021 salesforce.com, inc. All rights reserved.


37
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

5-2: Handle DML Errors and Exceptions

Goal:
Handle errors when inserting Contacts.

Note: If you performed the previous exercise in the Sandbox then continue to use the Sandbox for this
exercise - otherwise perform this exercise in your production org.

Tasks:

1. Print the list of reasons why Contacts could not be inserted into the database.
2. Test your code.

Time:
15 minutes

Instructions:

1. Continue working in the same org that you used for the previous exercise.

2. Print the list of reasons why Contacts could not be inserted into the database

A. In Developer Console, open the ContactsDML class and overwrite all of its contents
with ContactsDMLException.txt.
B. Complete the TODOs for the exceptionsDML method.

3. Test your code.

A. In Developer Console, open the ContactsDML_Test class and overwrite its contents
with ContactsDMLExceptionTest.txt.
B. Complete the TODOs for the exceptionsDMLTest method.
C. Run the test and verify it completed successfully.

©Copyright 2021 salesforce.com, inc. All rights reserved.


38
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

6-1: Deploy Code from Sandbox to Production (Optional)

Goal:
Deploy the two Apex classes previously created in the Sandbox to the Production org.

Tasks:
1. (Production) Change the deployment connection to allow inbound changes.
10. (Sandbox) Create and upload an outbound change set.
11. (Production) Validate and deploy the inbound change set.
12. (Production) Test changes to confirm that deployment was successful.

Time:
20 minutes

Instructions:

1. (Production) Change the deployment connection to allow inbound changes.

A. In Setup, browse to Environments | Deploy | Deployment Settings.


B. Update the settings to Allow Inbound Changes from the Dev sandbox.

2. (Production) Log into your sandbox.


3. (Sandbox) Create and upload an outbound change set.

A. In Setup, browse to Environments | Change Sets | Outbound Change Set.


B. Create a new outbound change set according to the following:
Name ContactsDML Classes
Description Includes ContactsDML class and corresponding test class.
Change Set ContactsDML (Apex Class)
Components ContactsDML_Test (Apex Class)
C. Upload your outbound change set to Production.
D. Log out of your sandbox org and log on to production.

©Copyright 2021 salesforce.com, inc. All rights reserved.


39
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

4. (Production) Validate and deploy the inbound change set called ContactsDML Classes.

Note: You may need to wait approximately 10 minutes before your inbound change set will be ready
for Production. It can take up to 30 minutes.

A. In Setup, browse to Environments | Change Sets | Inbound Change Sets.


B. Click ContactsDML Classes.
C. Click Validate.

Note: In our Trial production system, selecting the Default validation will not run any Apex tests.
In a real production environment, it will.

In order to see the result of running Apex tests as part of this deployment process, we will select
the Run local tests option which will execute any tests found in the change set plus any tests
that you may already have deployed into the production environment.

D. Select the radio button for Run local tests.


E. Click Validate and then click OK.
F. Click on the Deployment Status link shown near the top of the page.

Note: Notice that the page shows your two components deployed and a number of Apex tests
being executed. It may take several minutes for the tests to complete. You will see that several
Apex tests actually fail - this is to be expected in this training environment as we still have some
work to do in this org.

If this was a real production system, we would not be able to proceed with this deployment until
we address these problems. However, in our trial system, we can ignore these issues and
complete the deployment.

G. Return to the Inbound Change Sets page and click the Deploy link next to the
ContactsDML Classes change set.
H. Select the radio button for Default.
I. Click Deploy and then click OK.
J. In Setup, go to Custom Code | Apex Classes. Check that ContactsDML and
ContactsDML_Test are listed, indicating that the deployment completed successfully.

©Copyright 2021 salesforce.com, inc. All rights reserved.


40
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

K. Click on the ContactsDML_Test class and then click the Run Test button shown near
the top of the page
L. Verify that the test runs successfully.

©Copyright 2021 salesforce.com, inc. All rights reserved.


41
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

7-1: Define a Trigger

Goal:
Define a trigger on the Course_Delivery__c sObject.

Tasks:
1. Define a trigger.

Time:
5 minutes

Instructions:

1. Define a trigger.

A. In VS Code, create an empty Apex Trigger CourseDeliveryTrigger.


B. Modify the trigger to run against the Course_Delivery__c sObject.
C. Modify the trigger definition so that it runs both before insert and before
update.

©Copyright 2021 salesforce.com, inc. All rights reserved.


42
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

7-2: Define the Trigger's Business Logic

Goal:
Define the business logic of a trigger that only allows a Course Delivery to be saved if is not
scheduled to start on a holiday.

Tasks:
1. Create a Holiday.
2. Update the trigger.
3. Attempt to create a delivery that begins on a holiday.
4. Create a delivery that begins on a day that is not a holiday.
5. Attempt to update a delivery to begin on a holiday.

Time:
15 minutes

Instructions:

1. Create a Holiday.

A. In Setup, browse to Company Settings | Holidays.


B. Create a new holiday as follows:
Holiday Name New Year's Eve
Date (December 31st of the current year)
Time All Day
Recurring Holiday Deselected

2. Update a trigger.

A. In VS Code, open triggers\CourseDeliveryTrigger.trigger and overwrite its


contents with CourseDeliveryTrigger.txt.
B. Complete the TODOs.

©Copyright 2021 salesforce.com, inc. All rights reserved.


43
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

Note: Complete steps 3, 4, and 5 in the Salesforce UI.

3. Attempt to create a delivery that begins on a holiday.

A. Attempt to create and save a new Course Delivery with a start date of December 31 of
the current year. The save should fail.

4. Create a delivery that begins on a day that is not a holiday.

A. Create and save a new Course Delivery with a start date of January 1 of the
upcoming year. It should work.

5. Attempt to update a delivery to begin on a holiday.

A. Attempt to update the course delivery you just created so that its start date is on
December 31 of the current year. It should fail.

Question: Why do you need to test the behavior defined in both step 3 and step 5?

©Copyright 2021 salesforce.com, inc. All rights reserved.


44
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

8-1: Define an Apex Class

Goal:
Make a trigger easy to read and maintain by creating a handler class for it.

Tasks:
1. Create an Apex class.
2. Invoke the class from the trigger.
3. Test the trigger.

Time:
15 minutes

Instructions:

1. Create an Apex class.

A. In VS Code, create an Apex class CourseDeliveryTriggerHandler, overwriting all


of its contents with CourseDeliveryTriggerHandler.txt.
B. Complete the TODOs.

2. Invoke the class from the trigger.

A. In VS Code open triggers\CourseDeliveryTrigger.trigger and overwrite all


of its contents with CourseDeliveryTriggerRefactored.txt.
B. Complete the TODOs.

3. Test the trigger.

A. In VS Code, create an Apex class CourseDeliveryTriggerRefactored_Test and


overwrite its contents with CourseDeliveryTriggerRefactored_Test.txt.
B. In VS Code, run all of the tests in the CourseDeliveryTriggerRefactored_Test
class and ensure they executed successfully.

©Copyright 2021 salesforce.com, inc. All rights reserved.


45
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

9-1: Explore the Implicit Firing of Triggers

Goal:
Determine the actions that occur when a Course record is saved.

Tasks:
1. Open the Developer Console.
2. Update the status of a Course record to “Retired” in the UI.
3. Review the results in the Developer Console.

Time:
10 minutes

Instructions:

Note: If you do not have a working copy of CourseDeliveryTrigger, then create or replace it in your
org with the version EXFiles_solutions\7-2\CourseDeliveryTrigger.txt.

1. Open the Developer Console.

A. Open Developer Console now so that you are guaranteed to have an active trace flag
when you retire a course in the next step.

2. Update the status of a Course record to Retired in the UI.

A. Leaving the Developer Console open, switch to the Salesforce UI in another window.
B. Open the record detail page for the Course named [401] Data Recovery.
C. Change its status to Retired and save the record.

3. Examine the results in the Developer Console.

A. Return to Developer Console and open the most recent log.


B. Switch to the All (Predefined) perspective.
C. Enter START in the Filter input box of the Execution Log panel (case-sensitive).
D. In the Execution Log, notice that AfterUpdate event was fired multiple times for
CourseTrigger, followed by a BeforeUpdate event for CourseDeliveryTrigger, followed
by the execution of a workflow rule.

©Copyright 2021 salesforce.com, inc. All rights reserved.


46
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

E. The Save Order tab in the Execution Overview panel also shows the triggers firing, as
well as a workflow rule.
F. Click the Executed Units tab in the Execution Overview panel and click the entry for
the checkStatus method. Observe that it updated the Execution Log filter.
G. Notice the various operations called during the execution of this method in the
Execution Log panel.

©Copyright 2021 salesforce.com, inc. All rights reserved.


47
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

9-2: View the Events that Occur During a Rollback

Goal:
Determine the events that occur when an update action is rolled back.

Tasks:
1. Open the Developer Console.
2. Attempt to update the status of a Course record to “Retired” in the UI.
3. Review the results in the Developer Console.
4. Review the results in the UI.

Time:
10 minutes

Instructions:

1. Open the Developer Console.

A. Open Developer Console.


B. Confirm that the SFDC_DevConsole debug level is configured as follows:
i. DB, Apex Code and Profiling entries are set to Finest.
ii. System is set to Fine.

2. Attempt to update the status of a Course record to Retired in the UI.

A. Switch to the Salesforce UI in another window.


B. Open the record detail page for the [102] AWCA Network Course.
C. Change the Status field to Retired and try to save your change.
D. It will fail and display the error Course has enrolled students.

3. Review the results in the Developer Console.

A. Return to Developer Console and open the most recent log.


B. Switch to the All (Predefined) perspective.
C. In the Save Order tab in the Execution Overview panel, we see the same triggers and
workflow that fired in the last exercise are firing again (although more often).
D. In the Logs tab, right-click the most recent log and select the Open Raw Log option.

©Copyright 2021 salesforce.com, inc. All rights reserved.


48
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

E. In the tab that opens, search for the string "Status__c":"Retired". It occurs many
times, but you should examine the line that contains the first occurrence closely to see
that is part of a VARIABLE_ASSIGNMENT for triggerNew.
F. Note that this value of "Status__c" was never committed to the database.
G. Close the raw log and return to the regular log that has the All perspective open.
H. Click the Executed Units tab in the Execution Overview panel and click the entry for
the addError method. The entry in the log confirms that the addError method was
executed.

4. Review the results in the UI.

A. Return to the Salesforce UI, cancel your attempted edit and refresh the page.
B. Notice that the Status of each record in the Course Deliveries related list has not
changed and the Course Status is still Active, indicating that the save was rolled back.

©Copyright 2021 salesforce.com, inc. All rights reserved.


49
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

9-3: Use a Platform Event for Immediate Error Logging

Goal:
Create a custom error logging mechanism for the Course Delivery trigger using a custom object
and a Platform Event.

Tasks:
1. Define the schema of a Platform Event.
2. Publish the Event from an Apex class.
3. Subscribe to the Event from an Apex trigger.
4. Test the functionality of the event.

Time:
25 minutes

Instructions:

1. Define the schema of a Platform Event.

A. In Setup, navigate to Integrations | Platform Events


B. Define and save a new Error Message event as follows:
Label Error Message
Plural Label Error Messages
Object Name Error_Message
Description Custom error message details
Publish Behavior Publish Immediately
Deployment Status Deployed

©Copyright 2021 salesforce.com, inc. All rights reserved.


50
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

C. Define the following custom fields on the event:


Field 1 Field 2
Data Type Text Text
Label Source Component Error Message
Length 80 255
Field Name Source_Component Error_Message
Description Api name of the component Details of the error message
generating the error message. to be logged
Required (selected) (selected)

2. Publish the Event from an Apex class.

A. In VS Code, open CourseDeliveryTriggerHandler.cls and replace all of its


contents with CourseDeliveryTriggerHandlerPublish.txt.
B. Complete the TODOs.

3. Subscribe to the Event from an Apex trigger.

A. In VS Code, create a new Apex Trigger ErrorMessageTrigger, and replace all of its
contents with ErrorMessageTrigger.txt.
B. Complete the TODOs.

Note: You may find it helpful to refresh the sObject definitions to allow VS Code to recognize the
platform event definition.

4. Test the functionality of the event.

A. Open any Course Delivery record in the Salesforce UI.


B. Change its start date to the holiday you defined earlier and attempt to save it.
C. Observe the error message shown on the screen.
D. Verify that a corresponding Error Log record was created.

©Copyright 2021 salesforce.com, inc. All rights reserved.


51
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

10-1: Make Test Data Available to Test Methods

Goal:
Create test data to test the Certification application.

Tasks:
1. Create test data using a Static Resource.
2. Create test data programmatically.
3. Run the test.
4. Retrieve the Static Resource.

Time:
10 minutes

Instructions:

1. Create test data using a Static Resource.

A. In Setup, go to Custom Code | Static Resources and create a new Static Resource as
follows, uploading the file HolidaysForStaticResource.txt.
Name Test_Holidays
Cache Control Private

2. Create test data programmatically.

A. In VS Code, create a new Apex class CourseDeliveryTriggerHandler_Test and


replace its contents with CourseDeliveryTriggerHandler_Test.txt.
B. Complete the TODOs.

3. Run the Test

A. In VS Code, run the test in CourseDeliveryTriggerHandler_Test.cls.


Confirm the test completed successfully.

©Copyright 2021 salesforce.com, inc. All rights reserved.


52
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

4. Retrieve the Static Resource.

Note: You will not need to modify the Static Resource locally, but this example shows you one way to
download a file you created in Developer Console. You could have used the Wildcard Character
(*) to pull down all Static Resources, or you could have used the Org Browser.

A. In VS Code, add the following to your package.xml:


<types>
<members>Test_Holidays</members>
<name>StaticResource</name>
</types>

B. Use the updated package.xml to retrieve the source.


C. Verify that the Test_Holidays resource downloaded successfully into a directory called
staticresources.

©Copyright 2021 salesforce.com, inc. All rights reserved.


53
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

10-2: Write and Run an Apex Test

Goal:
Determine if the Certification application allows a Course Delivery to be created if it does not fall
on a holiday.

Tasks:
1. Write a test that tests the business logic of a trigger and a class.
2. Run the Test.
3. Explore Code Coverage.

Time:
10 minutes

Instructions:

1. Write a test that tests the business logic of a trigger and a class.

A. In VS Code, open CourseDeliveryTriggerHandler_Test.cls and replace its


contents with CourseDeliveryTriggerHandler_Test_TestMethods.txt.
B. Complete the TODOs.

2. Run the Test

A. In VS code, run the test in CourseDeliveryTriggerHandler_Test.cls and


ensure it executed successfully.

3. Explore the code coverage of the handler class.

A. In VS Code, open CourseDeliveryTriggerHandler.cls.


B. Click the Highlight Apex Code Coverage button in the VS code Status bar.

Note: If you receive a message that "No code coverage information was found for this file", make
sure that you have enabled the Retrieve-test-code-coverage option as instructed in Exercise 1-
2. Also, make sure you are viewing coverage for the correct Apex class.

©Copyright 2021 salesforce.com, inc. All rights reserved.


54
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

C. Notice that the code that was not covered by the test class (highlighted in red) is related
to ‘bad data’ – i.e. Course Deliveries that are scheduled on a Holiday.
D. Click the Highlight Apex Code Coverage button to turn coverage highlighting off.
E. Click on some other classes and experiment with viewing the Code Coverage. Keep in
mind that you need to run a class's corresponding tests to view its coverage
information.

©Copyright 2021 salesforce.com, inc. All rights reserved.


55
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

11-1: Refactor a Trigger to Avoid SOQL Limits

Goal:
Refactor the code for the Course Trigger to avoid the “Too many SOQL queries” error when
running a test with several records.

Tasks:
1. Examine the current Course trigger.
2. Test the trigger with a single record in the Salesforce UI.
3. Test the trigger with several records using unit test code.
4. Refactor the code to avoid a SOQL error.

Time:
15 minutes

Instructions:

1. Examine the current Course trigger.

A. In VS Code, open CourseTriggerHandler.cls.


B. Examine the code. What would cause it to receive a “Too many SOQL queries” error if
run with multiple records?

2. Test the trigger with a single record in the Salesforce UI.

A. Open the record detail page for the Course named [101] AWCA Server.
B. Change the status to Retired and attempt to save the change.
i. If the Course does not have any enrolled Attendees, then it should allow you to
change the status.
ii. If it does have enrolled attendees, then you will get a message telling you that the
“Course has enrolled students.”
iii. Either outcome indicates that the trigger was able to complete execution.

©Copyright 2021 salesforce.com, inc. All rights reserved.


56
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

3. Test the trigger with several records using unit test code.

A. In VS Code, open CourseTrigger_Test.cls and run its single test.


B. Observe the test failure with the red circle. Scroll to the bottom of the Output pane to
view more information about the failure.

4. Refactor the code to avoid a SOQL error.

A. In VS Code, replace the contents of CourseTriggerHandler.cls with


CourseTriggerHandler.txt.
B. Complete the TODOs.
C. Run the test and observe that it fails again, but for a different reason now. The SOQL
limit error is resolved but now a DML limit exceeded error appears in the output.

Note: In the next exercise you will refactor the trigger to resolve this new error.

©Copyright 2021 salesforce.com, inc. All rights reserved.


57
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

11-2: Refactor a Trigger to Avoid DML Limits

Goal:
Refactor the code for the Course Trigger to avoid the “Too many DML rows” error when running
a test with several records.

Tasks:
1. Examine the current Course trigger.
2. Refactor the code to avoid a DML error.
3. Re-test the trigger with several records using unit test code.

Time:
15 minutes

Instructions:

1. Examine the current Course trigger.

A. In VS Code, open CourseTriggerHandler.cls. Examine the code. What would


cause it to receive an error if run with multiple records?

2. Refactor the code to avoid a DML error.

A. Copy and paste the contents of CourseTriggerHandler.txt into the window (make
sure to use the 11-2 directory), overwriting all existing text.
B. Complete the TODOs.

3. Re-test the trigger with several records using unit test code.

A. In VS Code, open CourseTrigger_Test.cls and run the test. It should pass now.

©Copyright 2021 salesforce.com, inc. All rights reserved.


58
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

12-1: Create a Formula Field to Eliminate a Query

Goal:
Create a formula field so that the certification Id is available on the Certification Attempt object.

Tasks:
1. Create a hidden formula field on the Certification Attempt object.

Time:
5 minutes

Instructions:

1. Create a hidden formula field on the Certification Attempt object.

A. In Object Manager, add the following Formula custom field to the Certification
Attempt object.

Field Label Certification Id

Field Name Certification_Id

Formula Return Type Text

Formula CASESAFEID ( Certification_Element__r.Certification__c )

Description The 18-character record ID of the related Certification record

Field-level Security Leave as-is

Page Layouts Deselect all page layouts

©Copyright 2021 salesforce.com, inc. All rights reserved.


59
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

12-2: Create Fields for Counting Certification Elements

Goal:
Implement fields that will make the number of Certification Elements associated with a
Certification available on the Certification Attempt Element.

Tasks:
1. Create a roll-up summary field on the Certification object.
2. Create a hidden formula field on the Certification Attempt object.

Time:
5 minutes

Instructions:

1. Create a roll-up summary field on the Certification object.

A. From the Object Manager, add the following Roll-Up Summary field to the
Certification object.
Field Label Number of Certification Elements
Field Name Number_of_Certification_Elements
Summarized Object Certification Elements
Roll-Up Type COUNT
Field-level Security Leave as-is
Page layout Leave as-is

©Copyright 2021 salesforce.com, inc. All rights reserved.


60
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

2. Create a hidden formula field on the Certification Attempt object.

A. From the Object Manager, add the following Formula field to the Certification Attempt
object.

Field Label Number of Elements for Cert


Field Name Number_of_Elements_for_Cert
Formula Return Number
Type
Decimal Places 0
Formula Certification_Element__r.Certification__r.Number_of_Certification_Elements__c
Description The number of Certification Elements
Field-level Leave as-is
Security
Page layout Deselect all page layouts

©Copyright 2021 salesforce.com, inc. All rights reserved.


61
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

12-3: Create Collections to Filter the Query

Goal:
Create the query that will bring back Certification Attempt records.

Tasks:
1. Write code to create a query filter then loop over the SOQL results.
2. Create a trigger for Certification Attempt that calls the new handler class.
3. Test your new trigger logic.

Time:
20 minutes

Instructions:

1. Write code to create a query filter then loop over the SOQL results.

A. In VS Code, create a new Apex Class CertificationAttemptTriggerHandler,


overwriting its contents with the 12-3 version of
CertificationAttemptTriggerHandler.txt.
B. Complete the TODOs.

2. Create a trigger for Certification Attempt that calls the new handler class.

A. In VS Code, create a new Apex trigger CertificationAttemptTrigger,


overwriting its contents with CertificationAttemptTrigger.txt.

3. Test your new trigger logic.

A. Tail the Debug Logs in your terminal, being sure to filter for USER_DEBUG.
B. In the Salesforce UI, open the record detail page for the AWCA Network certification.
C. Open the related Certification Element AWCA Network Multiple Choice.

©Copyright 2021 salesforce.com, inc. All rights reserved.


62
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

D. Create a new related Certification Attempt as follows:


Record Type Multiple Choice
Certification Candidate Clara Petit
Status Complete/Pass

E. In your terminal, observe the debug statement that says createCertificationHeld


was called, followed by another debug statement that shows the ID of the Certification
Attempt record that was retrieved. This indicates that the new trigger logic fired
successfully.
F. Stop tailing the logs.

©Copyright 2021 salesforce.com, inc. All rights reserved.


63
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

12-4: Use a Map to Aggregate Results

Goal:
Aggregate the results of the query for use in determining if a candidate has passed all elements
of a certification.

Tasks:
1. Construct and use a Map to aggregate query results.
2. Test your new trigger logic.

Time:
20 minutes

Instructions:

1. Construct and use a Map to aggregate query results.

A. In VS Code, open CertificationAttemptTriggerHandler.cls and replace its


contents with the 12-4 version of CertificationAttemptTriggerHandler.txt.
B. Complete the TODOs.

2. Test your new trigger logic.

A. Tail the Debug Logs in your terminal, being sure to filter for USER_DEBUG.
B. In the Salesforce UI, open the record detail page for the AWCA Network certification.
C. In the Certification Elements related list, click the record named AWCA Network
Multiple Choice.
D. Create a new related Certification Attempt as follows:
Record Type Multiple Choice
Certification Candidate Arthur Franz
Status Complete/Pass
E. Click Save.
F. Return to the Terminal in VS Code where you are tailing the debug log.
G. Look for the following three entries, which indicate that the new trigger logic was fired
successfully:
i. One that indicates that the createCertificationHeld method was called.
ii. One that shows which Certification Attempt record was retrieved.

©Copyright 2021 salesforce.com, inc. All rights reserved.


64
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

iii. One that shows the size of passCounts equals one.


H. Stop tailing the logs.

©Copyright 2021 salesforce.com, inc. All rights reserved.


65
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

12-5: Create Certification Held Records

Goal:
Complete the solution to create Certification Held records for qualified candidates.

Tasks:
1. Create Certification Held records for qualified candidates.
2. Test your solution.

Time:
15 minutes

Instructions:

1. Create Certification Held records for qualified candidates.

A. In VS Code, open CertificationAttemptTriggerHandler.cls and replace its


contents with the 12-5 version of CertificationAttemptTriggerHandler.txt.
B. Complete the TODOs.

2. Test your solution.

A. Tail the Debug Logs in your terminal, being sure to filter for USER_DEBUG.
B. In the Salesforce UI, view the Certification record named AWCA Network.
C. Open the related Certification Element AWCA Network Multiple Choice.
D. Create a related Certification Attempt as follows
Record Type Multiple Choice
Certification Candidate Clara Morales
Status Complete/Pass
E. Return to the Terminal in VS Code where you are tailing the debug log.
F. Look for the following entries, which indicate that the new trigger logic was fired
successfully.
i. One that indicates that the createCertificationHeld method was called.
ii. One that shows which Certification Attempt record was retrieved.
iii. One that shows that the size of passCounts equals one.
iv. One that says a certification held record was added.

©Copyright 2021 salesforce.com, inc. All rights reserved.


66
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

©Copyright 2021 salesforce.com, inc. All rights reserved.


67
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

12-6: Use a Workflow to Avoid Creation of Duplicate Records (Optional)

Goal:
Create a workflow rule that will prevent duplicate Certification Held records from being created.

Tasks:
1. Create a new hidden text field.
2. Create a workflow rule to populate the new field.
3. Execute the workflow rule for all existing records.
4. Test your workflow rule.

Time:
10 minutes

Instructions:

1. Create a new hidden text field.

A. In the Object Manager, add the following Text field to the Certification Held object.

Field Label Cert Held Dup Key

Field Name Cert_Held_Dup_Key

Length 37

Unique Selected (case sensitive)

Field-level Security Read-Only for all profiles

Page layout Deselect all page layouts

©Copyright 2021 salesforce.com, inc. All rights reserved.


68
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

2. Create a workflow rule to populate the new field.

A. In Setup, go to Process Automation | Workflow Rules.


B. Create a new rule on the Certification Held object as follows:

Rule Name PopulateCertHeldDupKey

Evaluation Criteria created, and every time it’s edited

Run this rule if the formula evaluates to true

Formula true

C. Add a New Field Update as follows:

Name Cert Held Dup Key

Unique Name Cert_Held_Dup_Key

Field to Update Certification Held – Cert Held Dup Key

Text Options Use a formula to set the new value

Formula Certification__c & "|" & Certified_Professional__c

D. Save the field update and activate the rule.

3. Execute the workflow rule for all existing records.

A. In VS Code, run the following anonymous Apex to populate the hidden text field.
Database.update([ SELECT Id FROM Certification_Held__c ], false);

4. Test your workflow rule.

A. Open the Contact detail page for Clara Morales.


B. In the Certifications Held related list, verify that Clara Morales already holds the
certification named AWCA Network, then click New.
C. Enter the following information:

Certification AWCA Network

Date Achieved Today’s Date

D. Click Save. You should see the error message, “duplicate value found.” This indicates
that the new workflow rule was fired successfully.

©Copyright 2021 salesforce.com, inc. All rights reserved.


69
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

E. Click Cancel.

©Copyright 2021 salesforce.com, inc. All rights reserved.


70
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

13-1: Create a Simple Visualforce Page

Goal:
Create a simple Visualforce page that displays your name and Course record data.

Tasks:
1. Create a Visualforce page using the inline editor.
2. Add static text to the page.
3. Add a reference to the global user variable to display your name.
4. Modify your page to use the standard controller for the Course object.
5. Create a tabbed interface for a Course record.
6. Modify the page to use the Lightning Design System styling.

Time:
10 minutes

Instructions:

1. Create a Visualforce page using the inline editor.

A. Open a new browser tab to your org. Replace everything in the URL address bar after
force.com with /apex/HelloPage, then press ENTER. For example:

https://<instance>.lightning.force.com/apex/HelloPage

Note: A warning will be displayed that the page does not exist.

B. Click Create Page HelloPage.

2. Add static text to the page.

A. Click HelloPage in the lower left corner of the screen.


B. Replace lines 2-5 between <apex:page> and </apex:page> with the below code:

<b>Hello World</b>

C. Press CTRL + S to save the file. Note that the web page content changes.

3. Add a reference to the global user variable to display your name.

©Copyright 2021 salesforce.com, inc. All rights reserved.


71
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

A. Replace line 2 with the below code:


<b>Hello {!$User.firstName}</b>

B. Save the file. Note that the web page content changes.

4. Modify your page to use the standard controller for the Course object.

A. In the Salesforce UI, locate any Course record and copy its ID from the URL to the
clipboard.
B. Switch back to the tab hosting your Visualforce page and append to the end of the URL
?id=RecordId, replacing RecordId with the Course record ID you just copied, then
press ENTER.
C. Add the standard controller attribute to the page definition:
<apex:page standardController="Course__c">

5. Create a tabbed interface for a Course record.

A. Add the following markup for a tabbed interface to your Visualforce page:

<apex:page standardController="Course__c">
<b>Hello {!$User.FirstName}</b>
<apex:tabPanel >
<apex:tab label="Details">
<apex:detail relatedList="false"/>
</apex:tab>
<apex:tab label="Related Lists">
<apex:relatedList list="Course_Deliveries__r"/>
<apex:relatedList list="CombinedAttachments"/>
</apex:tab>
</apex:tabPanel>
</apex:page>

B. Save your page. Notice that the page is styled differently from what you may be used to
in the Lightning UI.

©Copyright 2021 salesforce.com, inc. All rights reserved.


72
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

6. Modify the page to use the Lightning Design System styling.

A. Add the LightningStyleSheets attribute to the page definition:

<apex:page standardController="Course__c"
lightningStylesheets="true">

B. Save your page and view the updated style.

©Copyright 2021 salesforce.com, inc. All rights reserved.


73
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

13-2: Create a Simple Technician Status Page

Goal:
Create a simple technician status page to display technician name, account name, and courses
they’ve registered for. Launch the page with a custom button.

Tasks:
1. Locate a record to be used as context during development.
2. Create a Visualforce page to only display the necessary fields and navigational links.
3. Create a custom button on the Technician Page Layout to launch the page.
4. Test the new page.

Time:
15 minutes

Instructions:

1. Locate a record to be used as context during development.

A. Open the record detail page for Contact Arthur Franz.


B. Copy and paste the 18-character Contact's record ID (starts with 003) from the URL
into a text file.

2. Create a Visualforce page in VS Code.

A. In VS Code, create a Visualforce Page named TechnicianStatusPage


and replace its contents with SimpleTechnicianStatusPage.txt.
B. Modify the following CLI command by replacing RecordId with the Contact record ID
copied earlier. Run the modified command from the Terminal to open a browser directly
to your VF page.
sfdx force:org:open -p "/apex/TechnicianStatusPage?id=RecordId"

NOTE: PowerShell users may need to remove the leading slash in front of /apex

C. Complete the TODOs in TechnicianStatusPage.page in VS Code.


D. Reload the page in your browser and note that the content changes.

©Copyright 2021 salesforce.com, inc. All rights reserved.


74
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

3. Create a custom button on the Technician Contact Layout to launch the page.

A. From Object Manager, open the Contact object and add the following new Button:

Label Technician Status

Name Technician_Status

Display Type Detail Page Button

Behavior Display in existing window without


sidebar or header.
(Known Issues)

Content Source Visualforce Page

Content TechnicianStatusPage

B. In the Technician Contact page layout, open the Mobile & Lightning Actions
category of the palette and drag your new Technician Status button to the Salesforce
Mobile and Lightning Experience Actions section of the page, placing it to the left of
New Event.

4. Test the new page.

A. Open the Contact detail page for Arthur Franz.


B. Click Technician Status.
C. Click Edit Technician Record, then click Cancel.

Optional Challenge: After reviewing your work the business has decided that they no longer want the
Technician Status page accessible from a button but would rather have it visible on the Contact record
page immediately below the Related List Quick Links component. The Visualforce page should only be
visible for Technician Contact records.

To achieve this you should:

1. Remove the Technician Status button from the page layout.

2. In Setup edit the Visualforce page and make it Available for Lightning Experience.

©Copyright 2021 salesforce.com, inc. All rights reserved.


75
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

3. Edit a Contact record page using Lightning App builder and add your Technician Status page using the
standard Visualforce component. Make sure the page is only visible when the Contact Record Type is
Technician.

©Copyright 2021 salesforce.com, inc. All rights reserved.


76
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

13-3: Reference a Controller Extension in a Visualforce Page

Goal:
Use the provided controller extension to display all Certification Held records related to the
current account in a Visualforce page embedded on the account page layout.

Tasks:
1. Create an Apex controller extension that queries all Certification Held records.
2. Create a page to display all Certification Held records.
3. Create a section on the Account Page Layout to display the new page.
4. Test your new page.

Time:
15 minutes

Instructions:

1. Create an Apex controller extension that queries all Certification Held records.

A. In VS Code, create a new Apex class AccountDisplayCertsHeld_CX, overwriting


all of its contents with AccountDisplayCertsHeld_CX.txt.
B. Complete the TODOs.

2. Create a page to display the Certification Held records.

A. In VS Code, create a new Visualforce page AccountDisplayCertsHeldPage,


overwriting its contents with AccountDisplayCertsHeldPage.txt.

3. Create a section on the Account page layout to display the new page.

A. In Object Manager, open the Service Vendor Account Layout page layout for the
Account object.
B. From the palette, click Visualforce Pages.
C. Drag and drop Section from the palette to below the Account Information section.

D. Enter the following information:


Section Name Certifications Held

©Copyright 2021 salesforce.com, inc. All rights reserved.


77
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

Detail Page Selected


Edit Page Deselect
Layout 1-Column

E. Click OK.
F. Drag and drop AccountDisplayCertsHeldPage from the palette to the new
Certifications Held section.
G. Click the Properties icon (wrench) in the top-right area of the
AccountDisplayCertsHeldPage element to open the Visualforce Page Properties.
H. Enter the following information:
Width (in pixels or %) 100%
Height (in pixels) 100
Show scrollbars Selected
Show label Deselected

I. Click OK.
J. Click Save.

4. Test your new page.

A. Open the Account detail page for the record named Alveswood Technologies.
B. Verify that the new section appears and that you can scroll through all the records.

©Copyright 2021 salesforce.com, inc. All rights reserved.


78
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

13-4: Creating a Read/Write Property in a Custom Controller

Goal:
Create a Visualforce page and custom controller to display a list of courses with corresponding
checkboxes. Utilize a wrapper class to render the checkbox property. Begin writing the action
method that will trigger the search.

Tasks:
1. Write the code necessary for the custom controller.
2. Create a page to display all courses.
3. Test your new page.

Time:
25 minutes

Instructions:

1. Write the code necessary for the custom controller.

A. In VS Code, create a new Apex class SearchCourses_CC, overwriting all of its


contents with SearchCourses_CC.txt.
B. Complete the TODOs.

2. Create a page to display all courses.

A. In VS Code, create a new Visualforce page SearchCoursesPage, overwriting all of its


contents with SearchCoursesPage.txt.

3. Test your new page.

A. From the Terminal in VS Code, use the CLI to open SearchCoursesPage.


B. From the Terminal in VS Code, tail the debug log.
C. Select one or more of the checkboxes next to the courses listed, then click See
Upcoming Course Deliveries. The page will refresh but will show no other visual
changes.
D. In the terminal, you should see an entry printed for each course you selected with the
phrase “Course Selected: <course name>”.

©Copyright 2021 salesforce.com, inc. All rights reserved.


79
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

E. Stop tailing the logs.

©Copyright 2021 salesforce.com, inc. All rights reserved.


80
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

13-5: Redirecting to a Results Page

Goal:
You must redirect the user to show the results of the search they have set up.

Tasks:
1. Create a new results page.
2. Write the code necessary to redirect the user to a new page.
3. Add code to the new page to display the course deliveries.
4. Test your new page.
5. Test the basic error handling.

Time:
25 minutes

Instructions:

1. Create a new results page.

A. In VS Code, create a new Visualforce Page ListCourseDeliveriesPage. You will


fill out its contents shortly.
B. Deploy the file by right-clicking inside of the editor and selecting SFDX: Deploy This
Source to Org.

2. Write the code necessary to redirect the user to a new page.

A. In VS Code, open SearchCourses_CC.cls and overwrite its contents with the 13-5
version of SearchCourses_CC.txt.
B. Complete the TODOs.

3. Add code to the new page to display the course deliveries.

A. In VS Code, return to ListCourseDeliveriesPage and overwrite its contents with


ListCourseDeliveriesPage.txt.

4. Test your new page.

A. From the VS Code Terminal, use the CLI to open SearchCoursesPage.

©Copyright 2021 salesforce.com, inc. All rights reserved.


81
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

B. Select one or more of the checkboxes next to the courses listed, then click See
Upcoming Course Deliveries. The page will refresh and show you the search results.
C. Verify that the Upcoming Course Deliveries page displays course deliveries related to
the course(s) you selected.
D. Verify that you can click New Search and return to the original search page.

5. Test the basic error handling.

A. Select NONE of the checkboxes next to the courses listed, then click See Upcoming
Course Deliveries. The page will display a message to select at least one course.

©Copyright 2021 salesforce.com, inc. All rights reserved.


82
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

13-6: Create a Page to Display a List of Records

Goal:
Create a Visualforce page that lets you paginate and filter Account records.

Tasks:
1. Create a page to display Account records.
2. Test your new page.

Time:
10 minutes

Instructions:

1. Create a page to display Account records.

A. In VS Code, create a new Visualforce Page AccountDisplayPage and overwrite all


of its contents with AccountDisplayPage.txt

2. Test your new page.

A. Use the CLI to open AccountDisplayPage in your browser.


B. Paginate through the records by clicking the > and < buttons, and test filtering the
records by setting Filter by to different values.

©Copyright 2021 salesforce.com, inc. All rights reserved.


83
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

13-7: Create a Simple Search Page

Goal:
Create a Visualforce page and custom controller to display a list of contacts based on the
results of a SOSL search.

Tasks:
1. Write the code necessary for the custom controller.
2. Create a page to search for contacts.
3. Test your new page.

Time:
15 minutes

Instructions:

1. Write the code necessary for the controller extension.

A. In VS Code, create a new Apex class DisplayContacts_CC and overwrite its


contents with those of DisplayContacts_CC.txt.
B. Complete the TODOs.

2. Create a page to display all courses.

A. In VS Code, create a new VF page DisplayContactsPage and overwrite its contents


with DisplayContactsPage.txt.

3. Test your new page.

A. Use the CLI to open DisplayContactsPage in your browser.


B. Type ar into the Search Text input box, then click Search. You should see a list of
contacts whose names include the search term.
C. Paginate through the records by clicking the > and < buttons.
D. Erase the value in the Search Text input box, then click Search. You should see an
error that your search term must be at least two characters long.
14-1: Defend Against SOQL Injection

©Copyright 2021 salesforce.com, inc. All rights reserved.


84
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

Goal:
Modify the controller of a Visualforce page to defend against SOQL Injection.

Tasks:
1. Create a custom Visualforce Controller.
2. Create a Visualforce page.
3. Search for an existing record.
4. Sanitize the code to defend against SOQL Injection attacks.

Time:
10 minutes

Instructions:

1. Create a Controller Extension and save it.

A. In VS Code, create an Apex class SOQLController and overwrite its contents with
SOQLControllerClass.txt.

2. Create a Visualforce page.

A. In VS Code, create a VF Page CertificationHeldQuickInfoPage and overwrite


its contents with CertificationHeldQuickInfoPage.txt.

3. Search for an existing record.

A. Use the CLI to open CertificationHeldQuickInfoPage in your browser.


B. Type CERTIFICATION-00001 in the textbox, then click Query.
C. Verify that the correct information is displayed.

4. Sanitize the code to defend against SOQL Injection attacks.

A. Type CERTIFICATION in the textbox, then click Query.


B. Try CERTIFICATION-0000*, CERTIFICATION-0000?, CERTIFICATION-0000_
or any other text to confirm that the query is not displaying unintended information.
C. Simulate a SOQL Injection attack by typing:
test' OR name like '%

©Copyright 2021 salesforce.com, inc. All rights reserved.


85
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

This has the effect of displaying all Certification Held records.


D. Return to SOQLController.cls in VS Code and replace its contents with
SOQLControllerClassSecured.txt.
E. Return to CertificationHeldQuickInfoPage in your browser.
F. Simulate a SOQL Injection attack again by typing:
test' OR name like '%

There should be no results displayed because the attack was mitigated.

©Copyright 2021 salesforce.com, inc. All rights reserved.


86
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

14-2: Write a Test Class for SearchCoursesPage

Goal:
Write an Apex test class to validate the navigation from the SearchCourses page to the
ListCourseDeliveries page.

Tasks:
1. Create the test class.
2. Run the test.
3. Verify the result.

Time:
20 minutes

Instructions:

1. Create the test class.

A. In VS Code, create an Apex class SearchCourses_CC_Test and overwrite its


contents with SearchCourses_CC_Test.txt.
B. Complete the TODOs.
C. Execute the test method in VS code.

2. Verify that the test ran successfully in VS code.

A. In VS code, open SearchCourses_CC.cls and observe the code coverage.

Optional Challenge: Update SearchCourses_CC_Test to make the code coverage for


SearchCourses_CC reach 100%.

©Copyright 2021 salesforce.com, inc. All rights reserved.


87
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

15-1: Create and Surface an Aura Component (Optional)

Goal:
Using the Aura programming model, create a Lightning component that will display the number
of days that your trial org has left before expiration. Surface the component on the Certification
App’s Home page.

Tasks:
1. Create an Apex class to return the number of days left.
2. Create an Aura Component to display the data.
3. Surface the Aura Component.

Time:
20 minutes

Instructions:

Note: When developing Lightning Components, it is helpful to enable Debug mode so that your code
is not minified.

1. Create the Apex class with an @AuraEnabled method that will return the number of days
remaining to your trial org as an Integer data type.

A. In VS Code, create an Apex class TrialExpirationController and overwrite its


contents with TrialExpirationControllerClass.txt.
B. Complete the TODOs.

2. Create the Aura component that will retrieve the number of days left from the Apex method
you just created and display the result.

A. In VS Code, create a new Aura component TrialExpirationAura. This will


automatically create several files that make up the component bundle.
B. Overwrite the contents of TrialExpirationAura.cmp with
TrialExpirationAuraComponent.txt.
C. Overwrite the contents of TrialExpirationAuraController.js with
TrialExpirationAuraController.txt.

©Copyright 2021 salesforce.com, inc. All rights reserved.


88
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

3. Surface the Lightning Component on the Home tab of the Certification App.

A. Modify the homepage of the Certification App and surface the TrialExpirationAura
custom component above the Assistant standard component at the top right of the
canvas.

©Copyright 2021 salesforce.com, inc. All rights reserved.


89
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

15-2: Create and Surface a Lightning Web Component (Optional)

Goal:
Create a Lightning Web Component that will display the number of days that your trial org has
left before expiration. Surface the component on the Certification App’s Home page.

Tasks:
1. Create an Apex class to return the number of days left.
2. Create a Lightning Component to display the data.
3. Surface the Lightning Component.

Time:
30 minutes

Instructions:

Note: When developing Lightning Components, it is helpful to enable Debug mode so that your code
is not minified.

1. Create the Apex class with an @AuraEnabled method that will return the number of days
remaining to your trial org as an Integer data type.

A. If you completed 15-1, proceed to step 2 as you have already done this.
B. If you have not completed 15-1:
i. In VS Code, create an Apex class TrialExpirationController and overwrite
its contents with TrialExpirationControllerClass.txt.
ii. Complete the TODO.

2. Create the Lightning Web Component and deploy it to your org.

A. In VS Code, create a Lightning web component trialExpirationLwc. The name is


case-sensitive.
B. Observe that the component bundle has been created consisting of 3 files – the html, js
and metadata files. Overwrite the contents of each project file with its corresponding
exercise file from as outlined in this table:
Project filename Exercise filename
trialExpirationLwc.html trialExpirationLwcHtml.txt

©Copyright 2021 salesforce.com, inc. All rights reserved.


90
Exercise Guide
Build Applications Programmatically on the Salesforce Platform (DEX450)

trialExpirationLwc.js trialExpirationLwcJs.txt
trialExpirationLwc.js-meta.xml trialExpirationLwcMeta.txt

3. Surface the Lightning Component on the Home tab of the Certification App.

A. Modify the homepage of the Certification App and surface the TrialExpirationLwc
custom component above the Assistant standard component at the top right of the
canvas.

©Copyright 2021 salesforce.com, inc. All rights reserved.


91

You might also like