Analytics Custom Event overridden by GTM? EventLabel always "(not set)" - google-analytics

I have this code triggering on clicking a tab.
window.ga('send', {
hitType: 'event',
eventCategory: 'PDP',
eventAction: 'ChangeTab',
eventLabel: 'lorem ipsum',
});
I have checked Analytics Real time and it shows up but the Event Label is always "(not set)"..
Is it Google Tag Manager's Click Event that is messing up my event?
If so how do I work around that? No Tag is fired on the Click.
EDIT: Is this the problem that this datalayer variable is defined in GTM?

This was the solution: https://stackoverflow.com/a/51705995/846348
We're including Analytics via GTM and using "Custom Dimension"/"Trackers" whatever that means.
class AnalyticsHelper {
static DEBUG = false; // requires https://chrome.google.com/webstore/detail/google-analytics-debugger/jnkmfdileelhofjcijamephohjechhna
static analyticsSend(data = {}) {
if (AnalyticsHelper.DEBUG) {
window.ga_debug = { trace: true };
}
window.ga(() => {
const trackers = window.ga.getAll();
const firstTracker = trackers[0];
const trackerName = firstTracker.a.data.values[':name'];
window.ga(`${trackerName}.send`, data);
});
}
}

Related

JS Event For WooCommerce Product View, Checkout, Order

I am using this code to handle the events on woocommerce remove from cart.
JS :
removeFromCartEventBind() {
document.body.addEventListener("click", (e) => {
const classList = e.target.className.split(" ");
const removeClasses = ["remove", "remove_from_cart_button"];
if (removeClasses.some((el) => classList.includes(el))) {
this.removeFromCart();
}
});
}
And I am calling the removeFromCart() function there.
removeFromCart() {
//Pushing data to tracker
console.log("Remove from Cart Called");
}
Are there any similar JS Events to track the other events like :
CartView, Checkout, Order, Search ..etc.

Google analytics App + Web slow send collect request

I am trying to implement GTM and new Google analytics web + app and I can see its taking 5sec to push data to google analytics.
I have tested with a fresh site and simple tracking event on click in link.
https://drive.google.com/file/d/1ILJLROq05OQwx3oXXCrOVXDeoxtbdKVw/view?usp=sharing
document.addEventListener('click', function (event) {
// If the clicked element doesn't have the right selector, bail
if (!event.target.matches('.btn-GA')) return;
// Don't follow the link
event.preventDefault();
// Log the clicked element in the console
console.log('Click......');
dataLayer.push({
"event": "wa_trigger",
"wa_event": "bounce_out",
"wa_action": "bounce_action",
"wa_label": "bounce_label"
});
}, false);
<a class="btn-GA" href="#">TEST CLICK</a>
================================================
UPDATE::::
Thanks for your answer. I noticed its really fast if I set true for the GA debug https://chrome.google.com/webstore/detail/google-analytics-debugger/jnkmfdileelhofjcijamephohjechhna and the hit comes fast and first others hit.. but when its off the hit comes at then end after 5sec.
And here screenshot from console:
https://drive.google.com/file/d/1a4n1WldESjbwTYkwiQ9PPX9RijigDApt/view?usp=sharing
Here the push and hit
Here push =====>
a.js:6 Google - dataLayer.push(): event: wa_trigger
a.js:6 ~ Object:
{
event: "wa_trigger",
wa_event: "logo-click"
}
Currently in memory: {event: "wa_trigger", wa_event: "logo-click", eventCallback: ƒ}
a.js:6 ~ Call Stack
a.js:6 ~ 20.140 s since Document Start
And here the hit: ====>
~ Data: {
events: [
{
en: "-logo-click",
_et: "2258",
ep.transport: "beacon"
},
{
en: "page_view",
_et: "36",
ep.transport: "beacon"
}
],
v: "2",
tid: "G-xxxxxx",
gtm: "xxxx",
_p: "109194814",
sr: "1440x900",
ul: "sv-se",
cid: "2129079382.1587074095",
dl: "http://www.site.lo/",
dr: "",
dt: "Site title",
sid: "1587312754",
sct: "5",
seg: "1",
_s: "2",
statusCode: 204
}
~ Network Hit: {frameId: 0, fromCache: false, initiator: "http://www.site.lo", ip: "216.58.207.206", method: "POST", …}
dlc.js:1208 ~ 26.208s since Document Start
dlc.js:1208 ~ 4.316s since last hit
It looks to be "by design":
One thing you might have noticed is the delay it takes for the hit to
be sent. When you load the page, you can see how the browser waits a
few seconds before dispatching the hit to GA. This is because GAv2
batches requests automatically, which, again, is a great feature
upgrade.
One thing you might have noticed is the delay it takes for the hit to
be sent. When you load the page, you can see how the browser waits a
few seconds before dispatching the hit to GA. This is because GAv2
batches requests automatically, which, again, is a great feature
upgrade.
By batching multiple hits into a single request, browser resources are
saved for other things. The delay is due to the browser waiting to see
if other hits should be dispatched together with the Page View.
https://www.simoahava.com/analytics/getting-started-with-google-analytics-app-web/
Be confident that the hit will fire before the user leaves the page !
Ok, I did my best to fix the issue and I used fetch to send the data directly to google server and skip the dataLayer and by using Callback function and a bit delay 1sec to wait for GA to be loaded.
Here how I did it and I am not sure if this is the best way or not but its working 100% and I got exact data on both old and old data.
BounceOut is the old data GA1
Bounce_out and Bounce_out_source is the new one GA2
trackAndBounceOut(url, callback) {
var action = this.state.bouncer.meta.partnerName
var label = this.state.bouncerId
var type = Session.page
window.dataLayer = window.dataLayer || []
var checkGA
setTimeout(function () {
if (ga && typeof ga.getAll == 'function') {
checkGA = true
} else {
checkGA = false
}
if (checkGA) {
var clientId = ga.getAll()[0].get('clientId');
var adSenseId = ga.getAll()[0].get('adSenseId')
var screenResolution = ga.getAll()[0].get('screenResolution')
var userLanguage = ga.getAll()[0].get('language')
var docReferrer = ga.getAll()[0].get('referrer')
var docLocation = ga.getAll()[0].get('location')
var debug = false // Enable for debug!!
var doctTitle = document.title
var stringUrlData = {
v: 2,
tid: 'G-XXXXXXXXXX',
gtm: 'XXXXXX',
_p: adSenseId,
sr: screenResolution,
ul: userLanguage,
cid: clientId,
dl: docLocation,
dr: docReferrer,
dt: doctTitle,
_dbg: debug ? 1 : '',
}
var urlString = Object.keys(stringUrlData)
.filter(analyticsKey => stringUrlData[analyticsKey])
.map(analyticsKey => analyticsKey + '=' + encodeURIComponent(stringUrlData[analyticsKey]))
.join('&')
var bounce_out = 'en=Bounce_Out&ep.Action=' + action
var bounce_out_source = 'en=Bounce_Out_source&ep.Action=' + type + '_' + action + '&ep.Label=' + type
fetch('https://www.google-analytics.com/g/collect?' + urlString + '&' + bounce_out, { method: 'POST' })
fetch('https://www.google-analytics.com/g/collect?' + urlString + '&' + bounce_out_source, { method: 'POST' })
if (Session.page == 'Partner') {
window.dataLayer.push(
{ 'event': 'pageEvent', 'Category': 'Partner page', 'action': 'Bounce Out', 'label': Session.page + '_' + action },
)
var partner_bounce_out = 'en=Partner_bounce-out&ep.Action=' + action
fetch('https://www.google-analytics.com/g/collect?' + urlString + '&' + partner_bounce_out, { method: 'POST' })
}
}
callback(action, type, label, url)
}.bind(this), 1000);
}
trackAndBounceOutRedirect(action, type, label, url) {
window.dataLayer.push(
{
'event': 'bounceOut',
'action': action,
'label': type + '_' + label,
'eventCallback': () => {
window.location.href = url
},
'eventTimeout': 1000
}
)
}
// And here then we call the main function and send the callback one:
this.trackAndBounceOut(this.state.bouncer.url, this.trackAndBounceOutRedirect)

Fullcalendar using resources as a function with select menu

Using Fullcalendar 4, I am trying to show/hide my resources using a select menu. When the user selects one of the providers from a menu, I want to only show that one resourc's events.
Above my fullcalendar I have my select menu:
<select id="toggle_providers_calendar" class="form-control" >
<option value="1" selected>Screech Powers</option>
<option value="2">Slater</option>
</select>
I am gathering the resources I need using an ajax call on my included fullcalendar.php page. I am storing them in an object and then trying to control which resources are shown onscreen:
document.addEventListener('DOMContentLoaded', function() {
var resourceData = [];
$.getJSON('ajax_get_json.php?what=schedule_providers_at_location',
function(data) {
$.each(data, function(index) {
resourceData.push({
id: data[index].value,
title: data[index].text
});
});
console.log(resourceData);
});
//below, set the visible resources to whatever is selected in the menu
//using 1 in order for that to show at start
var visibleResourceIds = ["1"];
//below, get the selected id when the the menu is changed and use that in the toggle resource function
$('#toggle_providers_calendar').change(function() {
toggleResource($('#toggle_providers_calendar').val());
});
var calendar_full = document.getElementById('calendar_full');
var calendar = new FullCalendar.Calendar(calendar_full, {
events: {
url: 'ajax_get_json.php?what=location_appointments'
},
height: 700,
resources: function(fetchInfo, successCallback, failureCallback) {
// below, I am trying to filter resources by whether their id is in visibleResourceIds.
var filteredResources = [];
filteredResources = resourceData.filter(function(x) {
return visibleResourceIds.indexOf(x.id) !== -1;
});
successCallback(filteredResources);
},
...
});
// below, my toggle_providers_calendar will trigger this function. Feed it resourceId.
function toggleResource(resourceId) {
var index = visibleResourceIds.indexOf(resourceId);
if (index !== -1) {
visibleResourceIds.splice(index, 1);
} else {
visibleResourceIds.push(resourceId);
}
calendar.refetchResources();
}
To make sure the getJSON is working, I have console.log(resourceData). The information in the console once it's gathered is:
[{id: '1', title: 'Screech Powers'}, {id: '2', title: 'Slater}]
... the above are the correct resources that can be chosen/rendered. So that seems to be okay.
On page load, no resources show at all, when resource id of '1' (Screech Powers) should be shown per my code. Well, at least, that's what I am trying to do right now.
When the menu changes, resources will show/hide, but not based on what's selected; the logic of only showing what is selected in the menu doesn't seem to be working.
I used to use a URL request for my resources: 'ajax_get_json.php?what=schedule_providers_at_location', and it worked fine! All resources show then their events properly. I am just trying to modify it by using a menu to show/hide the resources as needed.
Here's what I'm doing to make it happen so far! In case someone comes across this post ever, this will help.
Here's my code before my fullcalendar code.
var resourceData = [];
var visibleResourceIds = [];
$.getJSON('ajax_get_json.php?what=schedule_providers_at_location',
function(data) {
$.each(data, function(index) {
resourceData.push({
id: data[index].value,
title: data[index].text
});
});
});
$('#toggle_providers_calendar').change(function() {
toggleResource($('#toggle_providers_calendar').val());
});
My select menu with id 'toggle_providers_calendar' is the same as my original post. My fullcalendar resources as a function is the same too.
After the calendar is rendered, here are the changes I made to my toggle resources function:
// menu button/dropdown will trigger this function. Feed it resourceId.
function toggleResource(resourceId) {
visibleResourceIds = [];
//if select all... see if undefined from loading on initial load = true
if ((resourceId == '') || (resourceId === undefined)) {
$.map( resourceData, function( value, index ) {
visibleResourceIds.push(value.id);
});
}
var index = visibleResourceIds.indexOf(resourceId);
if (index !== -1) {
visibleResourceIds.splice(index, 1);
} else {
visibleResourceIds.push(resourceId);
}
calendar.refetchResources();
}
This causes the resources to show and hide properly. If the user selects "Show All" that works too!
In order to have a default resource show on load, I add this to my fullcalendar script:
loading: function(bool) {
if (bool) {
//insert code if still loading
$('.loader').show();
} else {
$('.loader').hide();
if (initial_load) {
initial_load = false;
//code here once done loading and initial_load = true
var default_resource_to_show = "<?php echo $default_provider; ?>";
if (default_resource_to_show) {
//set the menu to that provider and trigger the change event to toggleresrource()
$('#toggle_providers_calendar').val(default_provider).change();
} else {
//pass in nothing meaning 'select all' providers for scheduler to see
toggleResource();
}
}
}
},
I am using a bool variable of initial_load to see if the page was just loaded (basically not loading data without a page refresh). The bool of initial_load = true is set outside of DOMContentLoaded
<script>
//show selected date in title box
var initial_load = true;
document.addEventListener('DOMContentLoaded', function() {
My only current problem is that when toggleResource function is called, the all day vertical time block boundaries don't line up with the rest of the scheduler. Once I start navigating, they do, but I don't understand why it looks like this on initial load or when toggleResource() is called:
Any thoughts on how to correct the alignment of the allday vertical blocks?

Meteor google analytics

I have used this package for analytics.
My analytics is working for page view but for click event not working. I have written following code:
analytics.track("click", {
eventName: "downloadImage",
})
I'm not sure exactly what you're doing, but it should work something like this:
Template.myTemplate.events = {
'click button': function (event, template) {
analytics.track("Bought Ticket", {
eventName: "Wine Tasting",
couponValue: 50
});
}
}
What this does is tracks each time the button is clicked as a "Bought Ticket" event.

Media editor backbone js: Get the current action

I'm creating a plugin that adds an option to the native WP gallery.
When a new gallery is created (clicking the "Create Gallery" button in the media popup), a 'select' element is added, and I have a backbone event listening for the 'change' event of this 'select'.
However, I only want to listen for the change event when the gallery is being newly created, rather than when editing an existing gallery.
My code so far is:
wp.media.view.Settings.Gallery = wp.media.view.Settings.Gallery.extend({
events: function() {
var the_events = {};
//NEED TO GET STATE (ie, 'creating gallery for first time' rather than 'edit gallery'....
var is_create_gallery = true;
//IF WE'RE EDITING, SET IT TO FALSE
//--here--
if (is_create_gallery) {
_.extend( the_events, { 'change select[data-setting="gallerytype"]' : 'gallerytypechanged' } );
}
return the_events;
},
gallerytypechanged: function( e ){
e.preventDefault();
var self = this;
var gallery_type = jQuery( e.currentTarget ).val();
if( gallery_type != 'native' ){
self.update.apply( self, ['gallerytype'] );
}
return self;
},
template: function(view) {
return wp.media.template('gallery-settings')(view) + wp.media.template('gallery-type')(view);
},
});
Basically the --here-- code should be a check to determine whether we're editing an existing gallery, or creating a new one.
Does anybody know where to check which state we're in?
Thanks!
I assume you can detect the state of the gallery outside of your Backbone View.
You could set the is_create_gallery state when initializing the backbone view, then call your view constructor with the custom argument:
var newGallery = // determine the gallery state
var view = new wp.media.view.Settings.Gallery({newGallery: newGallery});
You can access the passed argument in your initialize function like this:
initialize: function (options) {
if (options.newGallery) {
_.extend(this.events, {
'change select[data-setting="gallerytype"]' : 'gallerytypechanged'
});
}
}
Since your events map will be either empty or contain one event, I would remove the events key completely and do the events initialization from initialize.

Resources