Skip to content

Commit

Permalink
Google Tag Manager dataLayer fix
Browse files Browse the repository at this point in the history
According to the GTM dev guide (https://developers.google.com/tag-manager/devguide) the dataLayer should be
set as a global variable and Google will be in charge of retriving such
variable with their gtm.js iframe.

Fixes adopted-ember-addons#127
  • Loading branch information
bugduino committed Nov 27, 2017
1 parent d72ec02 commit ccecf93
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 11 deletions.
25 changes: 15 additions & 10 deletions addon/metrics-adapters/google-tag-manager.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,18 @@ export default BaseAdapter.extend({

init() {
const config = get(this, 'config');
const { id, envParams } = config;
const dataLayer = getWithDefault(config, 'dataLayer', 'dataLayer');
const { id, envParams, dataLayer } = config;
if (dataLayer) {
set(this, 'dataLayer', dataLayer);
}

const dataLayerProp = get(this, 'dataLayer');
const dataLayerValue = getWithDefault(config, dataLayerProp, []);
const envParamsString = envParams ? `&${envParams}`: '';

assert(`[ember-metrics] You must pass a valid \`id\` to the ${this.toString()} adapter`, id);

set(this, 'dataLayer', dataLayer);
window[dataLayerProp] = dataLayerValue;

if (canUseDOM) {
(function(w, d, s, l, i) {
Expand All @@ -42,18 +47,18 @@ export default BaseAdapter.extend({
});
var f = d.getElementsByTagName(s)[0],
j = d.createElement(s),
dl = l !== 'dataLayer' ? '&l=' + l : '';
dl = l !== dataLayerProp ? '&l=' + l : '';
j.async = true;
j.src = 'https://www.googletagmanager.com/gtm.js?id=' + i + dl + envParamsString;
f.parentNode.insertBefore(j, f);
})(window, document, 'script', get(this, 'dataLayer'), id);
})(window, document, 'script', dataLayerProp, id);
}
},

trackEvent(options = {}) {
const compactedOptions = compact(options);
const dataLayer = get(this, 'dataLayer');
const gtmEvent = {'event': compactedOptions['event']};
const dataLayerProp = get(this, 'dataLayer');

delete compactedOptions['event'];

Expand All @@ -63,23 +68,23 @@ export default BaseAdapter.extend({
}

if (canUseDOM) {
window[dataLayer].push(gtmEvent);
window[dataLayerProp].push(gtmEvent);
}

return gtmEvent;
},

trackPage(options = {}) {
const compactedOptions = compact(options);
const dataLayer = get(this, 'dataLayer');
const dataLayerProp = get(this, 'dataLayer');
const sendEvent = {
event: compactedOptions['event'] || 'pageview'
};

const pageEvent = assign(sendEvent, compactedOptions);

if (canUseDOM) {
window[dataLayer].push(pageEvent);
window[dataLayerProp].push(pageEvent);
}

return pageEvent;
Expand All @@ -88,7 +93,7 @@ export default BaseAdapter.extend({
willDestroy() {
if (canUseDOM) {
$('script[src*="gtm.js"]').remove();
delete window.dataLayer;
delete window[get(this, 'dataLayer')];
}
}
});
21 changes: 20 additions & 1 deletion tests/unit/metrics-adapters/google-tag-manager-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ test('#trackEvent returns the correct response shape', function(assert) {
'eventLabel': 'nav buttons',
'eventValue': 4
};

assert.deepEqual(result, expectedResult, 'it sends the correct response shape');
});

Expand Down Expand Up @@ -78,6 +77,26 @@ test('#trackPage accepts a custom dataLayer name', function(assert) {
assert.deepEqual(result, expectedResult, 'it sends the correct response shape');
});

test('#trackPage accepts a custom dataLayer', function(assert) {
const adapter = this.subject({ config });
const dataLayer = [{foo: 'bar'}];
sandbox.stub(window, 'dataLayer').value(dataLayer);

const result = adapter.trackPage({
url: '/my-overridden-page?id=1',
title: 'my overridden page'
});

const expectedResult = {
'event': 'pageview',
'url': '/my-overridden-page?id=1',
'title': 'my overridden page'
};

assert.deepEqual(result, expectedResult, 'it sends the correct response shape');
assert.deepEqual(dataLayer, window.dataLayer, 'it sets the default dataLayer');
});

test('#trackPage accepts custom `keyNames` and returns the correct response shape', function(assert) {
const adapter = this.subject({ config });
sandbox.stub(window, 'dataLayer').value({ push(){} });
Expand Down

0 comments on commit ccecf93

Please sign in to comment.