I have a function which handles tracking of a certian event, like so:
var trackAddress = function (providedProduct, searchedProduct) {
_trackEvent('Address found', providedProduct, searchedProduct);
}
Now what will happen if searchedProduct is undefined or an empty string?
The thing is, in Google Analytics I can see that the sum of all event actions is equal to the total number of events. That is not the case in event labels.
What could be the cause for this?
I'm sure you know this, but for the sake of argument this is the anatomy of an event tracker:
_trackEvent(category, action, opt_label, opt_value, opt_noninteraction)
category (required): The name you supply for the group of objects you want to track.
action (required): A string that is uniquely paired with each category, and commonly used to define the type of user interaction for the web object.
label (optional): An optional string to provide additional dimensions to the event data.
value (optional): An integer that you can use to provide numerical data about the user event.
non-interaction (optional): A boolean that when set to true, indicates that the event hit will not be used in bounce-rate calculation.
Now in case a required parameter is missing (like action in your case) there's must be a mechanism within Google Analytics that will invalidate the event altogether. Conversely, an optional parameter, won't affect the event tracking but rather the report. To sum up, the result is the same: Loss of data.
A possible way around this to provide default parameters for your function arguments like so:
providedProduct = typeof a !== 'undefined' ? providedProduct : "defaultValue";
Further Reading: Setting Up Event Tracking
Related
I have two processes for our website: opt-in & opt-out.
We track the customer button clicks going into each process along with a cancel & confirm button that follow.
I have configured the GA4 events in GTM to fire on their respective buttons as follows:
Opt In:
Enter Button: Event Name: opt_in, Parameter Name: entry
Cancel Button: Event Name: opt_in, Parameter Name: cancel
Confirm Button: Event Name: opt_in, Parameter Name: confirm
Opt Out:
Enter Button: Event Name: opt_out, Parameter Name: entry
Cancel Button: Event Name: opt_out, Parameter Name: cancel
Confirm Button: Event Name: opt_out, Parameter Name: confirm
From my brief understanding of GA4, in order to report on these I need to have custom dimensions configured.
So I create the following custom dimensions:
Dimension Name: opt_in_entry, Event Parameter: entry
Dimension Name: opt_in_cancel, Event Parameter: cancel
Dimension Name: opt_in_confirm, Event Parameter: confirm
All OK.
When I add in the opt_out parameter is complains with the following error:
There is already a dimension or metric registered with this parameter
name.
Do I need to make my event parameter names unique or should I make my event names unique and ditch the parameters?
Your mistake is binding EPs (Event Parameters) to ENs (Event Names). They're somewhat independent dimensions.
So that you would understand, the limit GA4 sets on the number of distinct event names is about 500. While the limit for the number of distinct custom dimensions is only 50. There is no expectation whatsoever that you would make custom dimensions for specific events. That said, you want your custom dimensions and event properties quite vaguely named.
It is normal to have the same event property and its custom dimension to mean different things depending on event.
In your case, however, they mean the same thing. All you need to do is to name them properly. Instead of having:
Dimension Name: opt_in_entry, Event Parameter: entry
Dimension Name: opt_in_cancel, Event Parameter: cancel
Dimension Name: opt_in_confirm, Event Parameter: confirm
You could have
Dimension Name: entry, Event Parameter: entry
Dimension Name: cancel, Event Parameter: cancel
Dimension Name: confirm, Event Parameter: confirm
It's pretty common and straightforward to name your CDs just as you name your EPs. Much easier to debug and maintain them that way.
However, why are you really wasting three dimensions when you can really just put all of this in one dimension, say calling it CTA or even just type so that it could be reused with other events.
So now your tracking network requests would look like:
...
en: "opt-in",
ep.type: "entry",
...
ep.type can be whatever type you want to set there.
And in GA4, in the explorer, you would just pull two events: the opt-in and the opt-out and then just one type dimension for both events. You could also use a segment to limit the type values to these two events since pulling two event names can be awkward given how explorer is still has a long way to go in terms of usability.
This setup is quite elegant and doesn't waste space needlessly, while still allowing every kind of analysis.
Later on, you could reuse the type property/dimension with, let's say, a scroll event. Where you would store in the type variable whether the scroll was done with mouse, or nav bar. If that's valuable to know.
Or you could decide to track the add to cart clicks on product pages, and type could store whether the main CTA had been clicked, or the bottom add to cart CTA, or maybe something else.
This basic custom dimensions recycling is intended and it's a must for proper analytics tracking maintenance. Once you have more custom dimensions and events permutations than you can easily keep track of, it's time to document them and that documentation would be a part of your analytics SDR (Solution Design Reference). Larger and more complex implementations would definitely always have a document like that to make it easier to manage.
When google updated Firebase, it automatically took care of our old customised events and parameters. However, we now are trying to add more customised events from the new Event-scoped custom dimensions and metrics reporting.
In the new version, there is no such a thing called "register event", which I think it is totally cool, however, now, without having to register an event, even when our event name showed up in the tracking list, it did not capture any data.
Does anyone has encountered similar issues?
func generateInviteFrendsLink(user_id: String) {
let key = "invite_friend"
var parameters = [String: Any]()
parameters["user_id_invite_friend"] = user_id
Analytics.logEvent(key, parameters: parameters)
AppEvents.logEvent(AppEvents.Name(rawValue: key), parameters: parameters)
In my A/B testing (with Remote Configs), I want to know which variant performed better based on daily user engagement.
As I can not see the built-in goal metric "Daily user engagement" in the dashboard, so I want to create my custom.
Could I track an event with parameter VALUE and set it as a goal metric (based on its value) in A/B testing?
This is how want to do:
// Firebase Unity SDK
FirebaseAnalytics.LogEvent("time_spent", FirebaseAnalytics.ParameterValue, time_spent_in_seconds);
Thank you.
Declare an event in the class where you want the vent to be fired. I dont know the type of FirebaseAnalytics.ParameterValue as I am not familiar with firebase nor with your app. I will assume its a string:
public event EventHandler<string> raiseFirebaseEvent;
Wherever in your code (normally a different class where the event is declared, and after invoked which is the same) you need to add a listener to this event, this means to add a method to the event, to be called after in the event trigger.
In this other class you will have a method that will be the one to subscribe to the event:
prevate void FireBaseLogger(FirebaseAnalytics.ParameterValue value) {
FirebaseAnalytics.LogEvent("time_spent", value,
time_spent_in_seconds);
}
time_spent_in_seconds shoul be a variable of this other class I guess.
Somewhere in this class, usually in the constructor, or somewhere you know for sure that the code ejecution will go through there, you should subscribe to the event. For this you need a reference of your event holder class, where the event was declared:
EventHolderClassInstance.raiseFirebaseEvent += FireBaseLogger;
No arguments are passed in the subscription, just the method.
Then, in your EventHolderClass, when you invoke the event, passing the string parameter, the subscribed method will be called as long as the subscription was done prior the invocation.
raiseFirebaseEvent?.Invoke(this, FirebaseAnalytics.ParameterValue);
When there are no methods subscribed raiseFirebaseEvent is null, that is what the question mark is for. If there was no previous subscription raiseFirebaseEvent is null, and nothing happens.
In case FirebaseAnalytics.ParameterValueis not string type, change the type accordingly in the event and in the private method subscribed in the class where the listener is added, or where the subscription is made that means the same.
Not sure if that is what you were asking.
I want to parse a 'pushed' data layer string. I intend to use it to track click events and setup the appropiate funnels in Google Analytics, it looks as follows: products.view.19|view recent product|19
The first part (products.view.19) is the unique page identifier.
The second part (view recent product) is the action.
The last part is (19) is the action identifier, this way actions may be grouped and compared more easily.
So I did the following, I first created a trigger (it fires when a link has the tag 'data-trackclick' in it) which pushes the data value to a variable (variable for datalayer). However, now I want to split that variable in to 3 new variables, as described above. I selected 'javascript macro' for this but somehow it returns 'undefined'. The macro looks as follows:
function() {
var data = {{TrackClickData}};
var pieces = data.split('|');
if (pieces[0].length()) {
return pieces[0];
} else {
return data;
}
}
Obviously this didnt work since it would only run on the initial load and not (like I thought) when the macro was requested, so it should somehow be fired on the 'click' and then set the variables accordingly.
Is this possible to do? Or do I really have to add the dataLayer.push() in script tags?
A few things:
.length() is wrong, the property for array length is .length without the ()
if it exists, pieces[0] is not an array, then .length would return the string length, see How do you check for an empty string in JavaScript? for more standard way of checking for empty strings
Is this possible to do? There's virtually nothing you can't do with GTM, since you can write JavaScript code, you can do whathever you code allows you to do, and splitting a string to use parts of it as variables is certainly within the realm of possibilities.
My advise is to make your code work outside GTM first (eg test it in the browser console), then once it's all working, port it to GTM.
I am new to Web UI, Dojo, Java etc. If you are referring any advance topic please give some reading reference. It will help.
Context:
I have Gridx design using JsonStore, which takes a target + id for URL. With fixed "id" Grid loads well.
I have Dynamic Tree. It is working fine with lazy-loading etc.
Objective:
Based on click (or dblclick) event for a given node in Tree, I have to load Gridx with data. Hence, if tree node "id":7 is clicked, then JsonStore: /target/7 should be fetched and get loaded in Gridx.
Issues:
As you can guess, at start there is no valid "id" property to fill in JsonStore. In click event handler of tree, I will get this value, upon a user click. Hence, can't call gridx.startup() in "ready". Though I have "placed" the widget in "ready".
Hence, I have following snippet to handle,
<
// this function is called from tree event handler
function LatestTabGridxLoad( id ) {
console.log( "ID %s fetched.", id );
LatestTabGridxStore.idProperty = id;
LatestTabGridx.startup();
LatestTabGridx.body.refresh();
}
ready(function()
{
TabLatestAssetTree.startup();
LatestTabGridx.placeAt( "ReportMiddleTabLatestCenterContainer" );
}
Now, trouble is, at first time loading, JsonStore GET fired with /target/ alone, without any "id" without any user click. Hence, server responds with 405. Subsequently, when user clicks, again same HTTP GET without "id" results in HTTP 405. I am not able to somehow feed "id" to the GET URL. I have checked JSON, it is in perfect shape, as it works in standalone table, that is declarative(ly) defined.
Please suggest me ways to link a TREE node through its "id" to Gridx. Also suggest, if approach I am taking is right way to solve this problem.
Sorry, misunderstanding of the question. I thought it was about gridx tree but it is about regular gridx controlled by another widget.
The problem is in this line:
console.log( "ID %s fetched.", id );
LatestTabGridxStore.idProperty = id;
'idProperty' is the name of the JSON attribute which stores the ID. This will not change with each selection. If it is not set, JsonStore will assume it to be 'id'. What you intended to do was to modify the target property of the store to include the ID. This can done directly and will look something like the following (details are application specific)
LatestTabGridxStore.target = (someURL) + '/' + id;
After that, the content of gridx needs to be replaced using the new store setting. There are few ways to do it, the simplest being destroying the current gridx instance and replacing it with another one which uses the altered store.