A Guide to Event-Driven Data Layers with Adobe Post 2: Understanding & Accessing the Computed State of an EDDL with Adobe Launch & Data Layer Manager

In this series’ previous post, we detailed the history of the Event-Driven Data Layer, defined the event object, and justified and demonstrated event pushes. In this post we’ll dive a bit deeper into how Search Discovery’s Data Layer Manager (DLM) extension for Adobe Launch combines the information of multiple event objects into a single “Computed State.”

What is an event-driven data layer?

The event-driven data layer (or EDDL) is a layer of business information that engineers implement on a website to supply data for tags in tag management systems. This helps keep data consistent, increases the depth of data, and reduces the time maintaining tags within the tag management system. Read more about the history of EDDLs in the first post of this series, here.

Why we needed the Data Layer Manager extension

Let’s imagine that we have an EDDL that exists as a javascript Array at window scope. Let’s further imagine that our application is dutifully pushing event objects onto that array as significant events happen (pages are loaded and user interactions occur). As a data collection engineer, it becomes your job to recognize these events and send appropriate tags to analytics and marketing technology platforms. How is this done? 

Before DLM, the task of recognizing and processing events and event data was left entirely to the data collection engineer. Oftentimes, we’d ask the application developer to notify us by dispatching a custom event or by triggering an Adobe Launch Direct Call rule. When our rule(s) in Adobe Launch were triggered, we’d have some custom code that looks at the data layer array and tries to make sense of it.

In my experience, this custom code in Launch was seldom well-implemented and rarely understood by more than a few individuals in any given company. In the worst cases, this custom code would be duplicated across many rules, leading to Launch Library bloat and massive technical debt.

What the Data Layer Manager extension does

With the introduction of DLM, notification of data layer events and access to event data were handled centrally (and were no longer a concern of the data collection engineer). Notification and rule triggering is handled by the DLM’s “Data Layer Push” event. Access to event data is provided by DLM’s “Context Aware” data elements which provide fool-proof access to the computed state of the data layer at the time of each data layer push. 

Data Layer Manager automatically combines the payloads of multiple event objects into a single object as “dataLayerName.computedState”. As additional event objects are pushed, computedState is updated to reflect the new information (technically, computedState is a “getter” function and is only realized when it is referenced, but conceptually we’ll be treating it as if it were a plain object).  

If we look under the covers, there is also a computedState that is added to every event object as it is pushed. This event-specific computedState may be found at “dataLayerName[n].__meta.computedState”. The event-specific computedState is provided as a way to capture the state of the data layer at the time of the event object push in a stateful way in order to support asynchronous event processing in Launch (or other notified consumers) without data loss. 

It is perfectly fine to access these computedState objects directly; BUT, by using DLM’s Context Aware data elements, data will be automatically sourced from the correct computedState depending on whether the data element is being evaluated inside or outside of the context of a data layer push event. 

A helpful example to demonstrate how a computed state is maintained

Confused?  Let’s look at an example. Consider the following sequence of data layer pushes and console logs:
				
					var appEventData = window.appEventData || [];
appEventData._reset(); // Empty the data layer for this example

appEventData.push({
  "event" : "Page Load Started",
  "page" : {
    "name" : "Home Equity Lines of Credit",
    "title" : "Acme Corp : HELOC"
  }
});
console.log(
  "After 1st push\n", 
  JSON.stringify(appEventData.computedState, "", 2)
);

appEventData.push({
  "event" : "Form Displayed", 
  "form" : {
     "id" : "F_6543",
     "name" : "Apply for Financing"
  }
});
console.log(
  "After 2nd push\n", 
  JSON.stringify(appEventData.computedState, "", 2)
);

appEventData.push({
  "event" : "User Detected", 
  "user" : {
     "id" : "",
     "type" : "guest"
  }
});
console.log(
  "After 3rd push\n", 
  JSON.stringify(appEventData.computedState, "", 2)
);
				
			

Now let’s consider the value of appEventData.computedState after each push.  

After the first push, we’ll see this in the console. The computedState contains just the first pushed payload.

				
					After 1st push
{
  "page" : {
    "name" : "Home Equity Lines of Credit",
    "title" : "Acme Corp : HELOC"
  }
}
				
			
After the second push, the computedState contains the combined payloads of both pushes.
				
					After 2nd push
{
  "page" : {
    "name" : "Home Equity Lines of Credit",
    "title" : "Acme Corp : HELOC"
  },
  "form" : {
     "id" : "F_6543",
     "name" : "Apply for Financing"
  }
}
				
			
After the third push, the computedState contains the combined payloads of all three pushes.
				
					After 3rd push
{
  "page" : {
    "name" : "Home Equity Lines of Credit",
    "title" : "Acme Corp : HELOC"
  },
  "form" : {
     "id" : "F_6543",
     "name" : "Apply for Financing"
  },
  "user" : {
     "id" : "",
     "type" : "guest"
  }
}
				
			
Now let’s imagine that the user signs in and the application pushes a fourth event, as so:
				
					appEventData.push({
  "event" : "User Signed In", 
  "user" : {
     "id" : "98675555",
     "type" : "customer"
  }
});
console.log(
  "After 4th push\n", 
  JSON.stringify(appEventData.computedState, "", 2)
);
				
			
In the console, we would see this. The computedState now represents four pushes but the “user” key in the payload of the fourth overwrote the same key from the third payload. It is essential to understand this behavior when using the computedState object provided by Data Layer Manager.
				
					After 4th push
{
  "page" : {
    "name" : "Home Equity Lines of Credit",
    "title" : "Acme Corp : HELOC"
  },
  "form" : {
     "id" : "F_6543",
     "name" : "Apply for Financing"
  },
  "user" : {
     "id" : "98675555",
     "type" : "customer"
  }
}
				
			

How to access specific values from the computedState

So far, so good! Now let’s explore how we might access specific values from the computedState. Imagine that we want to access page.name and form.id in order to set some Adobe Analytics eVars.  

If we were doing this in AA custom code it might look like this: 

				
					// Old-school example - Works, but not best-practice
s.usePlugins = true;
s.doPlugins = function(s) {
  s.eVar1 = window.appEventData.computedState.page.name;
  s.eVar2 = window.appEventData.computedState.form.id;
}
				
			

While the above example would work, it’s not what I would consider to be best practice.  Let’s refine it a bit by using DLM’s Context Aware data element type. In order to do this, we first create a Data Element for each of the two variables as shown below for page.name. Note, we only need to specify the path relative to the computedState object.

Using the Data Layer Manager (DLM) to configure a data layer path.

Having done this for both variables, we can now reference them using _satellite.getVar in custom code like this:

				
					// Old-school example - Getting better.
s.usePlugins = true;
s.doPlugins = function(s) {
  s.eVar1 = _satellite.getVar("Page Name");
  s.eVar2 = _satellite.getVar("Form Id");
}
				
			

We can use these data elements all over the place in Launch (3rd party pixels, rule conditions, rule actions, you name it). 

Let’s go one step further and use these data elements to set Adobe Analytics variables from within an extension. Let’s assume for this example that we remove the AA Custom code shown above and that we have a data layer push that looks like this:

				
					var appEventData = window.appEventData || [];
appEventData.push({
  "event" : "Page Load Completed"
});
				
			

This is an example of a simple event object (no payload). Let’s create a Launch rule that is triggered by the data layer push. The event configuration uses the Data Layer Manager > Data Layer Push event and is triggered when the event key is “Page Load Completed”. 

Event configuration in the Data Layer Manager (DLM).

Now let’s add a few Rule Actions. The first uses the Adobe Analytics extension’s Set Vars action. Here, we just choose our eVars and set them to our data elements.

In the Data Layer Manager (DLM) action configuration, add the Adobe Analytics extension's Send Beacon Action then the Adobe Analytics extension's Clear Beacon Action.

After that, we add two more actions: the Adobe Analytics extension’s Send Beacon Action followed by the Adobe Analytics extension’s Clear Beacon Action. When complete, our rule looks like this:

A rule created in the Data Layer Manager can be saved and added to a library in the Launch environment.

If we save this rule, add all of our changes to a library, build that library to our Launch environment (most likely the Development environment), and visit the website where this environment is embedded, we’ll see our Launch Rule fire and see our Adobe Analytics beacon being sent. 

Great! Right? 

Yes and No. Yes, because we did all this without a single line of code. Yes, because all the application has to do is push the events. Yes, because all we have to do to send this info to Adobe Analytics is to create a couple data elements and a rule. No, because we’ve done this in a way that does not account for a page that does not have a “Form Displayed” event to provide the value for form.id.

Making event processing more flexible

Let’s address this issue in a way that makes our event processing more flexible so that we’ll only set eVar2 if a “Form Displayed” event is pushed. To do this, rather than just one Launch rule, we’ll create three.

Rule 1: Page Load Started [AA]

This rule is triggered when the “Page Load Started” event object is pushed to the data layer. It has an Adobe Analytics Set Variables action which sets eVar1 to %Page Name%. In the real world, it would most likely also set s.pageName, s.channel, and a handful of other variables.  Note that this rule DOES NOT Send the AA Beacon. It just sets the variables that are relevant to the data within the Page Load Started event payload. 

Rule 1. is triggered when the "Page Load Started" event object is pushed to the data layer. It has an Adobe Analytics Set Variables action.

Rule 2: Form Displayed [AA]

This rule is triggered when the “Form Displayed” event object is pushed to the data layer. It has an Adobe Analytics Set Variables action which sets eVar2 to %Form Id%.  Note again that this rule does not send an AA Beacon either. It just sets variables.

Rule 2. is triggered when the "Form Displayed" event object is pushed to the data layer. It has an Adobe Analytics Set Variables action.

Rule 3: Page Load Completed [AA]

This rule is triggered when the “Page Load Completed” event object is pushed to the data layer. Its job is not to set any AA variables—that job has been done by the previous two rules. Its job is to send the AA Beacon and Clear all AA Variables afterward. 

Save all this and test it out. You’ll see that the same beacon is created and sent when the “Form Displayed” event is between Page Load Started and Page Load Completed. If there is no Form Displayed event, the beacon is built, but without setting eVar2.

 Rule 3. is triggered when the "Page Load Completed" event object is pushed to the data layer. Its job is to send the AA Beacon and Clear all AA Variables afterward.

Rule 4: User Detected [AA]

Now let’s say that we want to track the User Detected data when that event exists. All we have to do is create the appropriate data elements and a User Detected [AA] rule that uses those data elements to set AA variables.

Create the appropriate data elements and a User Detected [AA] rule that uses those data elements to set AA variables.

We call this the “Bookends” pattern for page load sequence. We’ll dive deeper into this in a future post where we’ll explore tracking of Product Detail, Cart, and Checkout pages. 

Keep an eye out for this and other future data layer management posts, wherein we’ll include advanced considerations, structuring payloads, Launch and DLM, and troubleshooting advice.

Refer to Post 1 in this Guide to Event-Driven Data Layers with Adobe for additional context, and read more of our recent Analytics posts:

Do you have questions or comments? Reach out to talk with our Data Layer Management experts today!

Leave a Comment

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

Contact Us

Related Posts

Join the Conversation

Check out Kelly Wortham’s Optimization based YouTube channel: Test & Learn Community.

Search Discovery
Education Community

Join Search Discovery’s new education community and keep up with the latest tools, technologies, and trends in analytics.

Follow Us

Share

Share on facebook
Share on twitter
Share on linkedin
Scroll to Top