Adobe Campaign, Marketing Automation

ACC | How to JavaScript in Adobe Campaign

ACC - How to JavaScript in Adobe Campaign Classic

Adobe Campaign Classic utilizes JavaScript as the backend language for customizing various aspects of your instance, including workflows, libraries, web applications, and reports. The platform employs the Java Web Server called Tomcat for its operation. To execute JavaScript on the server, Adobe Campaign Classic utilizes a JavaScript engine called SpiderMonkey.

SpiderMonkey, developed by the Mozilla Foundation, is responsible for executing JavaScript code on the platform. Currently, Adobe Campaign Classic uses SpiderMonkey 1.8.5, which was released in 2012. This version was significant at the time as it implemented the ECMAScript 5 (ES5) specification. ES5 introduced several new features and improvements to the JavaScript language. Adobe Campaign also extensively utilizes E4X (ECMAScript for XML) and the last version of SpiderMonkey that supported E4X was 1.8.0. E4X has been gradually deprecated in newer versions of SpiderMonkey and is no longer widely supported in modern JavaScript environments.

What we have in ECMAScript 5

The new features in ECMA ES5 were following

  1. "use strict" : directive in JavaScript that enables strict mode within a specific scope or an entire script. When “use strict” is used at the beginning of a script or a function, it instructs the JavaScript interpreter to enforce a stricter set of rules and behaviors.
  2. Property Access on Strings: you can access individual characters or substrings within a string using property access notation. This allows you to retrieve or manipulate specific parts of a string based on their indices or positions.

To access a character at a specific index in a string, you can use square brackets ([]) with the index value inside, starting from 0. For example

var str = 'hello';
str[0]; // h
  1. Array.isArray(): Checks if a value is an array.
  2. Array.prototype.forEach(): Executes a provided function once for each array element.
  3. Array.prototype.map(): Creates a new array with the results of calling a provided function on every element in the array.
  4. Array.prototype.filter(): Creates a new array with all elements that pass the test implemented by the provided function.
  5. Array.prototype.reduce(): Applies a function against an accumulator and each element in the array to reduce it to a single value.
  6. Array.prototype.reduceRight(): Same as reduce(), but processes the array from right to left.
  7. Array.prototype.every(): Tests whether all elements in the array pass the test implemented by the provided function.
  8. Array.prototype.some(): Tests whether at least one element in the array passes the test implemented by the provided function.
  9. Array.prototype.indexOf(): Returns the first index at which a given element can be found in the array.
  10. Array.prototype.lastIndexOf(): Returns the last index at which a given element can be found in the array.
  11. Object.keys(): Returns an array of a given object’s own enumerable property names.
  12. Object.defineProperty(): Adds or modifies a property on an object, optionally specifying attributes such as enumerable, writable, and configurable.
  13. Function.prototype.bind(): Creates a new function that, when called, has its this keyword set to a provided value.
  14. JSON.parse(): Parses a JSON string and returns the corresponding JavaScript value.
  15. JSON.stringify(): Converts a JavaScript value to a JSON string.

What we do not have in ECMAScript 5?

Following is list of new features introduced to the next major release ECMAScript ES6 released in 2015

  1. let and const Declarations: Introduced block-scoped variables with let and block-scoped constants with const.
  2. Arrow Functions: Introduced a concise syntax for writing function expressions.
let hello = (scriptVersion) => `You will be missed in ${scriptVersion}`;
  1. Template Literals: Introduced a new way to create strings using backticks (`Hi there ${}`) with embedded expressions.
  2. Default Parameters: Allowed function parameters to have default values.
  3. Rest Parameters: Enabled the use of the rest parameter syntax (...) to represent an indefinite number of arguments as an array.
  4. Spread Syntax: Allowed an iterable (e.g., an array) to be expanded in places where multiple arguments or elements are expected.
  5. Destructuring Assignment: Provided a concise way to extract values from arrays or objects into distinct variables.
  6. Classes: Introduced a new syntax for defining classes, including support for constructor methods and inheritance.
  7. Modules: Introduced a standardized module format to organize and share JavaScript code between files.
  8. Promises: Introduced a built-in mechanism for handling asynchronous operations, simplifying callback-based async code.
  9. Array.from(): Created a new array from an array-like or iterable object.
  10. Array.find() and Array.findIndex(): Introduced methods for finding elements in an array based on a provided callback.
  11. Object.assign(): Allowed properties from one or more source objects to be copied to a target object.
  12. Enhanced Object Literals: Provided shorthand notations for defining object properties and methods.
  13. Symbol: Introduced a new primitive type to create unique identifiers, useful for defining object properties.
  14. Map and Set: Introduced new built-in data structures for collections with unique keys (Map) and unique values (Set).
  15. Iterators and Iterables: Introduced a protocol for iterating over data structures using the for...of loop and the Symbol.iterator method.

Among the new features, the one I will miss the most are:

  • Arrow functions: as they significantly reduce the amount of code I need to type. And they look amazing and everybody get feeling like you know what you are doing, just look at them.
//arrow functions
let m = (a, b) => a*b

//classic functions
var m = function (a, b){
  return a*b;
}
  • Template Literals: Every line has to be either concatenated with ‘+’ or using multiline feature of ES 5.
//template literals
const str = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. 
Aliquam imperdiet, massa at tempus scelerisque, urna sem hendrerit magna, a luctus odio urna vel nunc. 
Donec a volutpat magna. In iaculis lacus euismod magna fringilla tincidunt ut sed quam. 
Sed ac nisl non lacus dignissim vehicula vitae id purus.`;

const str2 = `Hello there ${name}`;

//old way
//do mind that this will not work with ' also adobe campaign does not recognize this syntax even though
//it is valid and will run without error
const str = "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\
Aliquam imperdiet, massa at tempus scelerisque, urna sem hendrerit magna, a luctus odio urna vel nunc.\
Donec a volutpat magna. In iaculis lacus euismod magna fringilla tincidunt ut sed quam.\
Sed ac nisl non lacus dignissim vehicula vitae id purus.";

const str2 = 'Hello there ' + name;
adobe campaign multi-line syntax highlight error
Look how they massacred my boy god father
  • Rest Parameters: Rest parameters are a feature introduced in ECMAScript 6 (ES6) that allow a function to accept an indefinite number of arguments as an array. It’s denoted by the ellipsis (...) followed by a parameter name. Here’s an example:
function sum(...numbers) {
  let total = 0;
  for (let number of numbers) {
    total += number;
  }
  return total;
}

console.log(sum(1, 2, 3, 4)); // Output: 10

In ECMAScript 5 you need to handle dynamic arguments manually. For that we use the arguments built-in object that provides access to the arguments passed into a function. It allows you to access the arguments dynamically, regardless of the number of parameters defined in the function’s declaration.

loadLibrary('xtk:shared/nl.js');
var sum = function () {
  	var sum = 0;
    if (arguments.length === 0)
      logError('No arguments provided!!')
    for (var i = 0; i < arguments.length; i++) {
      if (!NL.isEmpty(arguments[i]) && NL.isNumber(parseInt(arguments[i])))
        sum+=parseInt(arguments[i]);
    }
	return sum;
}

logInfo(sum(1,2,3,4));//06/01/2023 9:20:52 AM	js3	10
  • Spread Syntax: Spreading is the opposite of rest parameters. It allows an array to be expanded into individual elements. The spread syntax is also denoted by the ellipsis (...). Here’s an example:
const numbers = [1, 2, 3, 4];
console.log(...numbers); // Output: 1 2 3 4

const array1 = [5, 6];
const array2 = [7, 8];
const mergedArray = [...array1, ...array2];
console.log(mergedArray); // Output: [5, 6, 7, 8]

Destructuring Assignment: Destructuring allows us to extract values from arrays or objects into distinct variables. Here are examples of array and object destructuring:

// Array destructuring
const numbers = [1, 2, 3];
const [a, b, c] = numbers;
console.log(a, b, c); // Output: 1 2 3

// Object destructuring
const person = { name: 'Alice', age: 30 };
const { name, age } = person;
console.log(name, age); // Output: Alice 30

Next major thing introduced with ES 6 are Promises. Promise is an object that represents the eventual completion (or failure) of an asynchronous operation and its resulting value. Promises are commonly used when dealing with asynchronous operations such as fetching data from a server, making API requests, or handling time-consuming tasks.

The primary purpose of a Promise is to handle asynchronous code in a more organized and manageable way, avoiding excessive callback nesting (a phenomenon known as “callback hell”). Promises provide a clean syntax and a set of methods to handle the results of asynchronous operations.

Pollyfils


We may not have access to fancy features like spread syntax or destructuring in older ES versions, but what we can do is implement the functions we miss from newer ES versions. To achieve this, we use polyfills, which can be easily found and utilized if needed.


Polyfills in JavaScript are code snippets or libraries that provide modern functionality to older JavaScript environments that do not natively support those features. They help bridge the gap between older JavaScript versions and the latest ECMAScript specifications, allowing developers to use newer language features in older environments.

To create a polyfill for the Array.find() method in ES5, which was introduced in ES6 (ES2015), you can add the following code:

if (!Array.prototype.find) {
  Array.prototype.find = function(callback, thisArg) {
    if (this == null) {
      throw new TypeError('Array.prototype.find called on null or undefined');
    }

    if (typeof callback !== 'function') {
      throw new TypeError('callback must be a function');
    }

    var list = Object(this);
    var length = list.length >>> 0;
    var thisArg = arguments[1];

    for (var i = 0; i < length; i++) {
      var element = list[i];
      if (callback.call(thisArg, element, i, list)) {
        return element;
      }
    }

    return undefined;
  };
}

The above code checks if the Array.prototype.find method already exists. If it doesn’t, it creates the find method and assigns it a custom implementation. The polyfill replicates the behavior of Array.find() by iterating through the array and invoking the provided callback function on each element until a match is found.

Note that this polyfill checks for the existence of Array.prototype.find before creating it to prevent overriding native implementations if they already exist in the JavaScript environment.

Oh hi there đź‘‹
I have a FREE e-book for you.

Sign up now to get an in-depth analysis of Adobe and Salesforce Marketing Clouds!

We don’t spam! Read our privacy policy for more info.

#JavaScript #jsapi #JSSP #programming
Marcel Szimonisz
Marcel Szimonisz
MarTech consultant As a marketing automation consultant, I specialize in solving problems, automating processes, and driving innovation in my clients' marketing platforms.

I hold certifications in Adobe Campaign v6 (3x certified) and Salesforce Marketing Cloud (5x certified).

Additionally, I serve as a community advisor for Adobe Campaign, offering expert insights and guidance.

In addition to my professional pursuits, I also enjoy exploring various programming languages, CMSs, and frameworks, further enhancing my technical expertise and staying at the forefront of industry advancements.
Take a look at our subscription offering in case you are looking for a Marketing Automation Consultant.

Leave a comment

Your email address will not be published. Required fields are marked *

Similar posts that you may find useful

Adobe Campaign Classic tips
ACC Tips & Tricks, Adobe Campaign, Marketing Automation

ACC TIP | Column must appear in GROUP BY clause

1 minute read

Creating aggregated data reports may not be a daily task, but there are times when you might be tasked with generating such reports. For instance, you could group and track log clicks to create the coveted ‘Hot Clicks Report’. You tell yourself, ‘It’s nothing major,’ and believe you have an idea of how to do … Read more

Continue reading
SFMC tips and tricks
Salesforce Marketing Cloud, SFMC Tips & Tricks

SMFC TIP | How to query filtered data extension

less than a minute read

Easy way to segment your data is to use filtered data extension. Here we can use user interface to set up conditions as we like. When you want to add this newly filtered data extension to the SQL activity you will find that data extension cannot be found in the file browser. But it is … Read more

Continue reading
Marketing automation tips
Marketing Automation

TIP | Sending SMS with Unicode Characters

1 minute read

Are you planning to send SMS messages with Unicode characters? If so, you may be wondering why your messages are split into multiple messages even though they don’t exceed the character limit. Here’s what you need to know about sending SMS messages with Unicode characters. What are Unicode Characters? Unicode is a character encoding standard … Read more

Continue reading
SFMC tips and tricks
Marketing Automation, Salesforce Marketing Cloud, SFMC Tips & Tricks

SFMC TIP | The Power of Send Logging

1 minute read

Send logging in Salesforce Marketing Cloud is a feature that allows you to track the delivery, open, click, and other engagement metrics for the emails that you send from your account. This feature helps you to gain insights into the performance of your email campaigns and optimize them for better results. When you enable send … Read more

Continue reading
Salesforce Marketing Cloud Tips
Marketing Automation, Salesforce Marketing Cloud, SFMC Tips & Tricks

SFMC TIP | Troubleshooting Data Extensions

1 minute read

There are other aspects that I find rather unknown; while there is likely a rational explanation, the platform doesn’t provide straightforward answers. Here are some learnings of mine while working with data extensions: Importing in Contact Builder throws a validation error on the date field. The same file has been successfully imported via Email Studio.

Continue reading