Adobe Campaign, Marketing Automation

Master 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 tips and tricks
ACC Tips & Tricks, Adobe Campaign

How To Convert Base64 to PDF attachment

1 minute read

In this article, I will provide a simple trick for converting Base64 encoded data to PDF using JSAPI in Adobe Campaign Classic. Due to AC’s inability to attach Base64-encoded files directly to emails, this method can prove to be highly useful. Base64 data format that would be easy to use when supperted by Adobe Campaign […]

Continue reading
How to JavaScript in SFMC
Marketing Automation, Salesforce Marketing Cloud

JavaScript in Salesforce Marketing Cloud

3 minutes read

Salesforce Marketing Cloud uses JavaScript where a advanced customization is needed e.g. automations, cloud pages and even in message personalization. Last time we discussed how to JavaScript in Adobe Campaign, we discovered that it utilizes an older version of ECMAScript. However, it’s worth noting that Salesforce Marketing Cloud (SFMC) goes even further back and employs […]

Continue reading
How to lock workflow in Adobe Campaign Classic
Adobe Campaign, Marketing Automation

Avoid Editing Conflicts: How to Lock Workflow

6 minutes read

Many times, I have encountered situations where multiple individuals were simultaneously editing the same workflow. In such cases, the version that is saved last ultimately takes precedence. To avoid this issue, a simple solution would be to implement a workflow lock, which can prevent such scenarios from arising. We want to achieve following business logic: […]

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

Refresh Delivery in Transactional Journey

1 minute read

The process might seem straightforward at first glance—simply refreshing the email delivery content in Salesforce Marketing Cloud should suffice to receive the updated email contents. However, there’s more to consider. Salesforce Marketing Cloud utilizes server-side caching, which may display outdated content. Understanding when the cache refreshes isn’t always clear. In scenarios where immediate changes are […]

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

Proof email was previewed but not received

2 minutes read

There are many possible issues, and I will try to list all those I have come across during my times when I wondered where my email is. Contact is unsubscribed If the contact you are trying to preview an email with is on one of the global unsubscribe lists, or has unsubscribed or bounced status […]

Continue reading