From ccecf93bebe660ff856ebcd7972821999dc77a05 Mon Sep 17 00:00:00 2001 From: bugman Date: Mon, 27 Nov 2017 12:18:31 +0100 Subject: [PATCH] Google Tag Manager dataLayer fix 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 #127 --- addon/metrics-adapters/google-tag-manager.js | 25 +++++++++++-------- .../google-tag-manager-test.js | 21 +++++++++++++++- 2 files changed, 35 insertions(+), 11 deletions(-) diff --git a/addon/metrics-adapters/google-tag-manager.js b/addon/metrics-adapters/google-tag-manager.js index 3072893b..969ff861 100644 --- a/addon/metrics-adapters/google-tag-manager.js +++ b/addon/metrics-adapters/google-tag-manager.js @@ -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) { @@ -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']; @@ -63,7 +68,7 @@ export default BaseAdapter.extend({ } if (canUseDOM) { - window[dataLayer].push(gtmEvent); + window[dataLayerProp].push(gtmEvent); } return gtmEvent; @@ -71,7 +76,7 @@ export default BaseAdapter.extend({ trackPage(options = {}) { const compactedOptions = compact(options); - const dataLayer = get(this, 'dataLayer'); + const dataLayerProp = get(this, 'dataLayer'); const sendEvent = { event: compactedOptions['event'] || 'pageview' }; @@ -79,7 +84,7 @@ export default BaseAdapter.extend({ const pageEvent = assign(sendEvent, compactedOptions); if (canUseDOM) { - window[dataLayer].push(pageEvent); + window[dataLayerProp].push(pageEvent); } return pageEvent; @@ -88,7 +93,7 @@ export default BaseAdapter.extend({ willDestroy() { if (canUseDOM) { $('script[src*="gtm.js"]').remove(); - delete window.dataLayer; + delete window[get(this, 'dataLayer')]; } } }); diff --git a/tests/unit/metrics-adapters/google-tag-manager-test.js b/tests/unit/metrics-adapters/google-tag-manager-test.js index a0279ad5..68d7443e 100644 --- a/tests/unit/metrics-adapters/google-tag-manager-test.js +++ b/tests/unit/metrics-adapters/google-tag-manager-test.js @@ -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'); }); @@ -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(){} });