Fast Path To B2C Commerce Developer Certification - Module 4 - Forms, Transactions & Middleware Events
Fast Path To B2C Commerce Developer Certification - Module 4 - Forms, Transactions & Middleware Events
Developer Certification
Module 4
Forms, Transactions and
Middleware Events
Module 4.1: Forms
Objective - By the end of this module you will be able to define a form, render a form,
and use client-side JavaScript to submit the form and handle responses.
This module will cover:
• Form definition
• ISML template
• Controller route to render the from
• Controller route to handle form submission
• Client-side JavaScript that use Ajax to submit the form, and handle responses
• What is this functionality and why does it matter for implementations?
• Forms are an integral part of every commerce site: cart, account, checkout
• Understanding the inner workings of forms is essential B2C Commerce knowledge
Module 4.1: Form Metadata
Form Definition
Adds any specific js and css files for this form to handle client-side validation and
submission via Ajax:
assets.addJs('/js/newsletter.js');
Form fields with specific form attributes (use inspect to see attributes):
<input type=”input” class=”form-control” id=”newsletter-form-fname”
<isprint value=”${pdict.newsletterForm.fname.attributes}”
encoding=”off” />>
● Renders a page:
res.render('/newsletter/newslettersuccess', {
continueUrl: continueUrl,
newsletterForm: newsletterForm
});
Module 4.1: Form handling without client-side JS (version 1)
The handler route uses Response.json() to send a JSON object containing status and a message to the
client side:
Module 4.1: Form submission using client-side JS
SFRA uses client-side Javascript extensively to handle forms
Then use Ajax to post the form data to the controller handler route:
$.ajax({
url: url,
type:’post’,
data Type:’json’,
data: $form.serialize()
Finally define handler functions that receive the json object sent back by
the controller handler route:
success: function (data) {
$form.spinner().stop();
if (!data.success) {
formValidation($form, data);
} else {
location.href=data.redirectUrl;
}
}
Module 4.1: Cross-site request forgery (CSRF) protection
Implementing CSRF on SFRA forms
Add a CSRF middleware method to validate the ajax request (only when
using client-side submission):
Module 4.1: Form handling using client-side JS (version 2)
The localization framework allows the system to pick the right metadata based on current locale.
Using localized metadata, en_US states and fr_FR regions are shown properly for the corresponding
locales:
Module 4.2: Custom Objects and Transactions
• Objective
• By the end of this module you will be able to a create custom object to store a
newsletter subscription, and use a transaction to commit the custom object to the
database.
This module will cover:
• Custom Object creation
• Transaction methods
• Use of the Logger API
• Why does this functionality matter for implementations?
• Usage of Custom Objects is required in many implementations
• Transactions are required to persist data to the database
• The Logger API is used extensively to help with support for the storefront
Module 4.2: Using Custom Objects (COs) in your application
Extend your application to store custom data
● Sometimes you won’t find any System Object that can be used for your custom data. In that case,
Custom Objects are the answer.
● For best practices, consult this XChange article.
● COs have quota restrictions that are enforced on every instance: build a strategy to clean them up, or
face the consequences when the quota is exceded!
Since the CO must be persisted to the database, you must use a Transaction. There are 2 flavors:
● Explicit transaction: you decide when to commit or rollback
var txn = require('dw/system/Transaction');
txn.begin();
try {
//Create or modify any Persistent object using a Mgr class: CustomObjectMgr, OrderMgr, etc
txn.commit();
} catch(e) {
//Oops!
txn.rollback();
}
As a good developer, you should log informational messages, warnings and errors that could happen during normal
execution of your code. Have a logging strategy that will guide support when your code runs in production.
Logs are available under https://<your_instance>/on/demandware.servlet/webdav/Sites/Logs
● Use dw.system.Logger
var Logger = require('dw/system/Logger');
● Log to a custom file and/or category if needed for complex integrations:
Logger.getLogger("adyen_checkout_log", "payment_auth_category").error(...);
Logger.getLogger("payment_auth_category").warn(...);
● Otherwise, messages get logged to the general info, warn, error and fatal logs:
● Be aware that Business Manager supports enabling and disabling of log levels and categories
○ In production, only error and fatal should be logged to keep logs smaller
○ Turn on other levels as needed to evaluate a problem
○ On SBs, turn on other levels to evaluate the execution of your code (i.e. during system testing)
Module 4.2: Create a CO and use a transaction (version 3)
• Objective
• By the end of this module you will be able to a enclose a transaction inside a
middleware event
This module will cover:
• Middleware Events in documentation
• Middleware Events implementation in SFRA
• What is this functionality and why does it matter for implementations?
• Middleware events are necessary to control when in a middleware chain a specific
business requirement (i.e. a transaction) needs to execute.
Module 4.3: SFRA Middleware Events
Do you know who is extending your route?
Consider this: your controller might be extended by another controller (really!) but you have a
transaction in your controller that “should” be executed at the end of the route to account for any
changes to the data.
To handle these situations, the server module supports middleware events your code can listen
for.
To make sure your transaction is the last thing that gets executed by the route, use the
route:beforeComplete middleware event, as follows:
Module 4.3 Demo: Use a Middleware Event