Expand my Community achievements bar.

SOLVED

Is it possible to use the Code Editor for "Data Element" to query two different objects and return one value?

Avatar

Level 2

We moved from GTM to DTM a little over 6 weeks ago and I'm still getting to grips with its functions.

Scenario:

I need to capture the page name in a Data Element using a DTM script/property used over two different domains.

Domain 1 has a dataLayer, where I can use the standard 'JS Object' option to retrieve the page name e.g. digitalData.page.name

Domain 2 does not have a dataLayer and I have to use the CSS selector for where a business page name has been defined (not document.title) to retrieve the page name e.g. Data Element option is CSS Selector, #WebMIPageName and return 'other' value of 'content'

What I would like to know if there a way to write a piece of code using the code editor option in Data Elelment to look for both and return the page name?

e.g.

IF digitalData.page.name OR #WebMIPageName then return value or 'content'

As you can tell I have no code/java experience so I hope this makes sense..

Thanks for reading...

1 Accepted Solution

Avatar

Correct answer by
Community Advisor

Your best bet is to get the data layer in pace on the second site, but we don't always have that option.

Assuming that you need to make do, you might try one of these strategies :

Option One :

1) Use one set of data elements that reference the window.digitalData object.

2) Add a bit of code that runs as soon as possible on the page that populates the data layer if it does not exist.

window.digitalData = window.digitalData || {};

window.digitalData.page = window.digitalData.page ||{}

window.digitalData.page.name  = window.digitalData.page.name || document.getElementById("WebMIPageName").textContent();

...

Option Two :

Create three data elements for every attribute.

1) Create a data element called "page.name" as a custom JS type with the following code:

return (_satellite.getVar("dl_page.name")||_satellite.getVar("css_page.name"));

2) Create a data element called "dl_page.name" as type JS Object.  This would reference digitalData.page.name

3) Create a data element called "css_page.name" as type CSS Selector. #WebMIPageName returning content (as you described above).

In your other rules, reference the data element created in step 1.  It will first, try to get a value from dl_page.name. If it does not return a value, then it will attempt to resolve "css_page.name".

Option Three :

As you described, you could put all the logic into a single custom JS data element but as in option one, this would be code heavy.

Here's what that might look like.

Create a data element called "page.name" as a custom JS type with the following code:

return _satellite.getVar("window.digitalData.page.name") || document.getElementById("WebMIPageName").textContent();

This solution uses an undocumented feature of DTM's _satellite.getVar where you can directly access window scoped objects. What's nice is that it will fail gracefully if any part of the referenced object does not exist.  This feature has not been moved forward into Launch, so you would have an issue if you wanted to bring these data elements from DTM into Launch at some point.

Option Four, Five, Six

There are other options. 

FWIW, My favorite is Option Two.

View solution in original post

2 Replies

Avatar

Correct answer by
Community Advisor

Your best bet is to get the data layer in pace on the second site, but we don't always have that option.

Assuming that you need to make do, you might try one of these strategies :

Option One :

1) Use one set of data elements that reference the window.digitalData object.

2) Add a bit of code that runs as soon as possible on the page that populates the data layer if it does not exist.

window.digitalData = window.digitalData || {};

window.digitalData.page = window.digitalData.page ||{}

window.digitalData.page.name  = window.digitalData.page.name || document.getElementById("WebMIPageName").textContent();

...

Option Two :

Create three data elements for every attribute.

1) Create a data element called "page.name" as a custom JS type with the following code:

return (_satellite.getVar("dl_page.name")||_satellite.getVar("css_page.name"));

2) Create a data element called "dl_page.name" as type JS Object.  This would reference digitalData.page.name

3) Create a data element called "css_page.name" as type CSS Selector. #WebMIPageName returning content (as you described above).

In your other rules, reference the data element created in step 1.  It will first, try to get a value from dl_page.name. If it does not return a value, then it will attempt to resolve "css_page.name".

Option Three :

As you described, you could put all the logic into a single custom JS data element but as in option one, this would be code heavy.

Here's what that might look like.

Create a data element called "page.name" as a custom JS type with the following code:

return _satellite.getVar("window.digitalData.page.name") || document.getElementById("WebMIPageName").textContent();

This solution uses an undocumented feature of DTM's _satellite.getVar where you can directly access window scoped objects. What's nice is that it will fail gracefully if any part of the referenced object does not exist.  This feature has not been moved forward into Launch, so you would have an issue if you wanted to bring these data elements from DTM into Launch at some point.

Option Four, Five, Six

There are other options. 

FWIW, My favorite is Option Two.

Avatar

Level 2

Hi Stewart,

Many thanks for your help. Due to a regulatory requirement the site has to go live by a set date, with or without a dataLayer, but I will have one roughly 2-3 weeks later.

Option two was a no brainer as I already created two of the data elements in your suggestion. I had one with an event to record the CSS selector page name as an eVar which I was then using in "Process Rules" in the report suite to populate the page name where it wasn't set. Works, but not very slick.

This is exactly what I was after, thanks again.