Skip to main content
JavaScript Data Processor: Deep Dive
Updated over a week ago

The JavaScript data processor is available in all BlueConic connections that use data processors. The JavaScript data processor allows you to apply custom-written JavaScript code functionality to a data source.

This article provides deeper technical details and best practices for the JavaScript data processor so you can better understand how it works under the hood and troubleshoot any issues that arise.

Adding and configuring the JavaScript data processor

For instructions on adding and configuring the JavaScript data processor in a connection, refer to the main JavaScript data processor article.

Adding the Log data processor

It can sometimes be difficult to know what the input of the JavaScript data processor is, especially if you use linked files or add a different processor beforehand. To get this information, you can use the Log data processor.

When you add the Log data processor before the JavaScript processor, the JSON will be logged in the log file, which can be downloaded from the run history and directly copied to the preview of the JavaScript data processor.

Note: When you use linked files, the data from the files is aggregated into one object, which serves as input for the data processor. This is a nested structure, which initially may make it more advanced to work with.

Tip: To prevent an excess number of entries from being added to the log file, either stop the run manually or use the First x lines data processor.

Filtering data

You may want to apply logic to determine if a record has to be skipped. Unfortunately, this cannot be done by the Filter data processor. Instead, you can return nothing in the JavaScript data processor:

if (data.col1 === "val1" && data.col2 === "val2") {
/*this record will be skipped*/
return null;
}

/*this record will be handled*/
data.extra = data.col1 + "_myPostFix";

Filtering Timeline events

When you are exporting Timeline events, you can filter them using the JavaScript data processor. For example:

profile.timelineEvents = profile.timelineEvents.filter(order => {
return order.getValues("product")
.some(product => product.getValue("id") === "PRD-1");
});

This example filters "Order" Timeline events that have a product with ID "PRD-1."

Transforming one record to multiple records

You can use the JavaScript data processor to make one line into multiple lines. For example, if you are exporting to an activation platform and a profile property value contains multiple email addresses, you will want to export it as multiple rows, since the activation platform cannot handle comma-separated values.

So instead of one line, as such:

customer_id;email
CUST-1;[email protected],[email protected]

...you would export it as multiple lines, as such:

customer_id;email
CUST-1;[email protected]
CUST-1;[email protected]

In the JavaScript data processor, you can use this:

/* this would create a line for email values */
/* note: this also has the consequence, when there is no email in the profile, the profile is skipped */
return profile.getValues("email").map(singleEmail => {
return {...data, ...{email: singleEmail}};
});

Transforming a string to multiple events

If you receive a string with channels (comma separated) that have to be translated to multiple events, use the following:

/* example value for "channels": "EMAIL,SMS,PHONE,POST" */
data.events = data.channels.split(",").map(channel => {
return {
id: channel,
date: data.myDate
}
});

Note: You have to expose events.id and events.date as additional fields. The mapping part will translate it to multiple Timeline events because it notices the “events” attribute as an array.

Using the last run date

In some cases, you may want to filter out profiles based on the last run date. This is illustrated here:

if (lastRunDate < new Date(profile.getValue("mydateproperty"))) {
return null;
}

Understanding syntax for getting a value

When using the JavaScript data processor as an import processor, use data.fieldID to get the value of a field, where fieldID is the header of the column in the imported file.

When using it as an export processor:

  • Use profile.getValue(property_id) to load the value from the profile, where property_id is the property ID of the profile property in question.

  • The data object will be empty, so if you want to get something from the profile, use profile.getValue("myprop"), for example.

    • Note: When other data processors are configured before the JavaScript data processor and they write something to the data object (e.g., export group properties), this data will be available in the data object and can be used in the JavaScript data processor.

Working with hyphenated profile properties

JavaScript does not accept hyphens, so inputting profile properties with a hyphenated ID returns an error. Instead of using data.mobile_phone_contact_accent_-_blueconic = "...";, use data["mobile_phone_contact_accent_-_blueconic”] = "...";.

Using the Post Processor Connection

When using the JavaScript data processor as an export processor in the Post Processor Connection, you can use data.profile_property_ID (e.g., data.email) to get access to data of the profile property in the "Profile properties to use" step of the connection.

Tip: Make sure to define the mapping in the Post Processor Connection so that this data is updated.

Note: You can add new data fields as appropriate (under "Additional target fields" at the bottom of the editor window) so these can be used in the "Define the mapping" step.

Tackling maintenance tasks

You can also use the JavaScript data processor in the Post Processor Connection to tackle the following maintenance tasks:

Emptying profile properties:

data.empty_data = "";
  • For mapping: empty_data => profile property to “set or clear”

Assigning test groups:

data.random_value = (Math.floor(Math.random() * 10) + 1) * 10;
  • For mapping: random_value => target profile property

Setting value counts:

data.count_value = data.my_property.length;
  • Make sure you replace my_property with the profile property ID of the source property.

  • Properties to use: source property

  • For mapping: count_value => target profile property

Filtering profile properties:

  • If you need a simple filter:

data.filtered = data.prop_1.filter(value =>
    value === "my filter value");
  • If you need more expression power, use a regular expression:

const searchRegExp = /my filter value/;

data.filtered = data.prop_1.filter(value => searchRegExp.test(value));
  • Properties to use: source property

  • For mapping: filtered => target profile property

Touching profiles:

data.new_value = new Date().getTime().toString();
  • For mapping: new_value => target profile property

Converting values to numbers:

data.converted = data.my_property.map(value => {
const decimalSeparator = ","
const numberStr = value.includes(decimalSeparator)
? value.substring(0, value.indexOf(decimalSeparator))
: value;

/* replace all non-numerical characters */
return numberStr.replace(/\D/g, "");
})
  • Make sure you replace my_property with the profile property ID of the source property.

  • Properties to use: source property

  • For mapping: converted => target profile property

Did this answer your question?