How to update a dataLayer variable? - javascript

We initially push an object containing variables to the dataLayer:
dataLayer.push({
'environment': {
'userName': 'abc',
'id': 123,
'clicks': 0
}
});
We now want to increase the value of environment.clicks with every click a user makes.
How to do that? When we push it via
dataLayer.push({
'environment': {
'clicks': 123
}
});
The dataLayer Array may get 10.000s of entries. How to properly update the variable?

The way to update a datalayer variable is to push a variable, either when a "native" GTM event occurs or alongside a custom event. So basically you are it right.
As for your worries that the DL might get to many entries - the dataLayer gets a new entry on every click in any case (GTM adds that itself), so the additional entries for your variable will probably do not matter that much.
If you still want to avoid this you can update a global Javascript variable and use that in GTM. Google Tag Manager has access to all variables on your page (you will still get all the click events in your dataLayer).
The dataLayer also has a set method that allows you to write to the Datalayer directly, which is apparently what you are looking for. You need to acquire your GTM instance and then you can set values:
var gtm = window.google_tag_manager[{{Container ID}}];
gtm.dataLayer.set('balloonsPopped', undefined);
Details are e.g. here in a Bounteous article. You could use this in a custom HTML tag to update the click count before the click event fires your tag.
Also the dataLayer is reset on page load. It would take a hell of a single page app to collect 10 000s of clicks per pageview.
This is tagged Google Analytics. If you plan to track the clicks in GA remember that a GA session expires after 500 clicks, so the results might not be what you expect (also the free version only has only 10M hit per month, click tracking will quickly exhaust this). And of you want to track the number of click in GA then you would need an event or something to track the click, so the number of events is basically the metric you are looking for, or you could create a custom metric and set it to "1" in your GA call (meaning that it will be incremented by one on every call).

Quoting from the documentation:
It's important to note that pushing a variable of the same name as an existing variable to the data layer will cause the existing value to be overwritten by the new value
Simply pushing an entry with the same variable name and the updated value should work.

Couldn't you use a holder? Something like:
var click_value_holder = dataLayer.environment.clicks;
dataLayer.push({
'environment': {
'clicks': (click_value_holder + 1)
}
});

Related

Google Tag Manager - Count amount of pageviews

I've made an event in Google Tag Manager, which triggers when a specific page is loaded.
The Event label is the value of my user defined variable SearchCounter with type: Custom JavaScript.
In 'SearchCounter' I have the following JS:
function(){
var counter;
if(localStorage.getItem("count_search") === null || localStorage.getItem("count_search") === 'undefined'){
localStorage.setItem("count_search", "1");
return localStorage.getItem("count_search");
}
else{
counter = parseInt(localStorage.getItem("count_search"));
counter = counter + 1;
localStorage.setItem("count_search", counter);
return localStorage.getItem("count_search");
}
return localStorage.getItem("count_search");
}
When I don't have the item in my local storage already, it still give's me 7 instead of 1. Then I'll press F5: count_search = 17, And again f5: 27. A CTRL-F5 gives me 37.
It should be 1, 2, 3, 4, 5 etcetera.
I hope someone can help me to implement a counter-alike function in Google Tag Manager, so I can send the amount of searches to GA, when a goal has been achieved. So, When someone clicks a specific button a would like to get the value of count_search, to send it to GA within an event.
Thanks very much.
First of all this metric is given by google analytics by default so i don't see why ur trying to store it somewhere else. If you dont want the avg that google uses you can just store a custom dimension at 'Session' level with the sessionID and those in a custom report open Sessions by pageviews. Here is info about it.
On the other hand, if you insist doing it your way i think even if this works it isn't the best approach you would get a much better result storing the counter in a custom dimension at 'Session' level. (It ll overwrite the value each time for a given session and you ll end up with the last one send)
Hope it helps.
What you need to do is changing the name of the parameter saved in the localStorage. I don't know why, but count_search does not work. I tested your setup and encountered the same weird effect where the count_search item is summing up to astronomical numbers. Using a different name like thisIsMyPageViewCounter works just fine though! Probably count_search is accessed by another object in the document or window and you managed to get a value out of it by chance.
If you want to add the page view count to an event, I do not see any other way than creating both a Custom HTML Tag to set the counter and a Custom JS Variable to return the count.
This is the Custom HTML Script to be added to each page view:
<script>
(function() {
if(localStorage.getItem("thisIsMyPageViewCounter") === null || localStorage.getItem("thisIsMyPageViewCounter") === 'undefined') {
localStorage.setItem("thisIsMyPageViewCounter", 1);
} else {
var counter = 0;
counter = parseInt(localStorage.getItem("thisIsMyPageViewCounter"));
counter = counter + 1;
localStorage.setItem("thisIsMyPageViewCounter", counter);
}
})();
</script>
This is the Custom JS Variable to be added as a value to the event:
function() {
pageviewCounter = parseInt(localStorage.getItem("thisIsMyPageViewCounter"));
return pageviewCounter;
}
I hope this helps!

Firebase convert generated ID to numeric ID

This is an old question but no answers found. Old answers' source links are dead, old functions are deprecated.
I've look at these topics (1, 2) amongst others, and also current Firebase guide.
function writeUserData(name, win, loss) {
firebase.database().ref('users/').push({
name: name,
wins: win,
losses: loss
});
}
I need to pull or somehow convert the unique ID from each push to numeric ID: 1, 2
UPDATE:
Here's what I'm trying to do:
2 users can login at the same time from 2 different browsers.
1st user hits button 'log-in' or 'start' will be written as users/1/{user's attributes} on firebase.
if there's an existing user
(somehow I need to check that on the user-end), the next user hits
'start' will be written as users/2/{user's attributes} on firebase. Else (no existing user), the user will be written as user1. This is where I think I need push instead of set. I can use set to add more users from 1 browser, but if i open the app from another browser/chrome incognito, the app will just reset the existing users.
if a user refreshes or closes the browser, that user will be removed from firebase so another user can log-in.
I've tried different methods (loop, creating new var...) to achieve this.
Rather than .push, try to use .set or .update. In that way you can set your own generated key. But as already suggested, this may not be the best approach.

GTM issue with double event created instead of dl push

I use this code in GTM , that retrieves a number from another domain and stores it on a dataLayer value, with a dL.push. I want the variable to be available on a specific event.
(function ()
{
var callbackMethodName = "adnscallback";
window[callbackMethodName] = function(data) {
(function() {
dataLayer.push({
'event': 'ga_new',
"id2": data.uid
});
})();
}
var sc = document.createElement("script");
sc.id = "script_" + callbackMethodName;
sc.src = "https://example.site.com/getnumber?callback=" + callbackMethodName;
document.body.appendChild(sc);
})();
But I already create an event called ga_new (hardcoded, that creates all sort of values on the page) and when this codes run, it creates another event called ga_new, instead of pushing the values on the existing event. This creates issues with the tags as they are double firing.
What iam doing wrong and the push, instead of appending the data, it creates the event again?
You can not "update" a custom event. The "event" keyword is a signal to GTM that it needs to update its internal data structure with new values.
The datalayer variable in the page is an array of objects, the internal datastructure is a single object into which new values are merged, and existing values for the same keys are overwritten. GTM overwrites the native implementation of the JS "push" method with its own code that watches for the "event" keyword. So every time it encounters the "event" key changes are triggered.
You either need a different name for the event, or you change the trigger so that it only fires when both the "ga_new" event are set and the data.uid field is set.

How to trigger data collection with SiteCatalyst?

I just get started with Adobe SiteCatalyst and I am just wondering how could I trigger the sending of colllected data to the server with it.
Imagine the situation that I have some custom event, for example event1 = 'user opened help us popup'. After user opens popup - I'm assigning data to props:
s.events = "event1";
s.prop1 = "name of popup";
After that I'm checking the analytics debugger (https://www.adobetag.com/d1/digitalpulsedebugger/live/DPD.js) and it says that I didn't get this data.I suppose that I need somehow send it to SiteCatalyst, but I can't figure out how. Please help me.
There are two triggers for Adobe Analytics: page view s.t() and click/event s.tl()
Based on your scenario, you are probably going to want to use the s.tl() trigger.
Here is an example of what the code should look like:
s.events = "event1";
s.prop1 = "name of popup";
s.linkTrackVars = "events,prop1";
s.linkTrackEvents = "event1";
s.tl(true,'o','popup opened');
The vars you want to be tracked in the s.tl() call should be listed in linkTrackVars. If there is more than one, delimit with a comma (no spaces, no s namespace). If you have any events to track, you must also specify the events in s.linkTrackEvents. Basically, s.linkTrackEvents should be the same value as s.events (except if you are serializing an event, do NOT include the serialization ID in s.linkTrackEvents)
As for the s.tl() call, above is an example of what you might pass for a general event, but args will vary depending on what you are trying to track. (refer to link for details).

NetSuite - Fields are not being set in the sales order after I set context to 'scheduled'

Hope you can assist.
I am currently trying to conduct one of the most simplest tasks via a user event script - that is to set a new value in the 'discount rate' field on the sales order. My script works fine when testing it on the client, but when the scheduled script is triggered, the field fails to set/update.
The following code is within a 'beforesubmit' operation. Can you spot what I have done wrong?
function beforeSubmit_discountVAT(type){
if(nlapiGetContext().getExecutionContext() !='scheduled')
return;
var getDiscountVal = nlapiGetFieldValue('discountrate');
var correctDiscount = getDiscountVal / 1.2;
nlapiSetFieldValue('discountrate', correctDiscount);
}
In short - All i want to do is deduct the discount value by 20%. Can you use 'nlapiSetFieldValue' when a user event script is triggered from a scheduled script?
Thanks in advance.
AWB
When editing an existing record, nlapiSetFieldValue cannot be used in a Before Load event on fields that are stored with the record. From the function's JSDocs:
Sets the value of a given body field. This API can be used in user event beforeLoad scripts to initialize field on new records or non-stored fields.
nlapiSetFieldValue can thus only be used reliably in Before Load on new records or non-stored fields.
Realizing this is a month old so you've probably found a solution, I would move your code to the Before Submit event. I tested this using a Scheduled Script:
var customer = nlapiLoadRecord('customer', '31294');
nlapiSubmitRecord(customer);
and User Event on the Customer record, Before Submit event:
if (nlapiGetContext().getExecutionContext() === 'scheduled') {
nlapiSetFieldValue('url', 'http://www.google.com/', false);
}
This works as expected for me in a 2013.1 Sandbox environment.
Using nlapiSubmitField in After Submit as mentioned in the other answer is an unnecessarily long operation that will use extra governance units. Not a huge deal if that's the only thing your script is doing, but if you ever expand the script or add looping, it can add up quickly in terms of performance and governance usage.
Also, it may not be necessary, but you should ensure that getDiscountVal is a Number by doing:
var getDiscountVal = parseInt(nlapiGetFieldValue('discountrate'), 10);
If it comes back as a String then your division operation may give a strange result which may also cause nlapiSetFieldValue to fail or set the field to an odd value.
two suggestions
Make sure that your script is being executed by adding a few nlapiLogExecution statements
Instead of doing it in beforesubmit, change this field in aftersubmit function using nlapiSubmitField
"Can you use 'nlapiSetFieldValue' when a user event script is triggered from a scheduled script?"
Yeah Absolutely yes.Context is also correct its scheduled.
Please make sure that you are submitting the record nlapiSubmitRecord(recordObj) at the end.
If you are not comfortable with nlapiSubmitRecord() you can obviously use nlapiSubmitField()
If still you get stuck up then please paste the complete code so that we could assist you.
Cheers!!!

Categories