Google Analytics Events - when are they send? - javascript

My "application" is a single web page (myPage.html) displaying items on a Google Map. So it is not a scenario where the user navigates among several pages.
Therefor I am using events to track the interactions. However, I find it strange to believe what I see in the statistics.
I have checked the events for syntax and it seems to be OK.
_gaq.push(['_trackEvent', 'MyApp', 'ChangeTav', newTab]);
_gaq.push(['_trackEvent', 'MyApp', 'Load', 'itemType', loadTime]);
....
What I wonder about, I do add Arrays to to _gaq object, but when are these actually send? What happens if the user closes the browser? And is there a way for me to "force" sending these values?
The other way around, user stays on the page for some time, values get added to _gaq, but how I do make sure they not getting lost?
-- Update --
With the push I simply add an Array to an Array, or is this wrong? So in this particular moment nothing happens, I did not see any callbacks or overridden methods. Please correct if I am missing something.
-- Update 2 --
http://code.google.com/apis/analytics/docs/tracking/asyncUsageGuide.html
It seems to be different whether I use sync or async. For async (I am using) ...
To push an API call onto the queue, you must convert it from the traditional JavaScript syntax into a command array. Command arrays are simply JavaScript arrays that conform to a certain format. The first element in a command array is the name of the tracker object method you want to call. It must be a string. The rest of the elements are the arguments you want to pass to the tracker object method. These can be any JavaScript value.
When I do init with var _gaq = _gaq || []; it becomes an array. However, I do never see values being removed from the queue (_gaq), so I'd assume they are never send.
--- OK, here we go ---
http://code.google.com/apis/analytics/docs/gaJS/gaJSApi_gaq.html#_gaq.push
This function is named push so that an array can be used in the place of _gaq before Analytics has completely loaded. While Analytics is loading, commands will be pushed/queued onto the array. When Analytics finishes loading, it replaces the array with the _gaq object and executes all the queued commands. Subsequent calls to _gaq.push resolve to this function, which executes commands as they are pushed.

I believe, it's send as soon as you call it. Provided that the _gaq has been initialized. Depends on where you put the GA init code.

The .push method you are referring to is only for arrays. With Objects, you can define it yourself, you are not overriding anything.
Arrays in js can't have custom indexes / labels, if they do, they are objects.
If you run
var a= {"a":"b"};
var b = ['a','b'];
b.push("c");
a.push("c","d");
You will get an error , function a.push is not defined.
a is an object, b is an array. The push function only exists in the prototype of Array.
To observe when exactly the stuff is tracked, you can use the Net panel in Firebug and check for a _utm.gif file being requested.

Related

Persistant variable with Gmail scripting (Google Apps Script) [duplicate]

In a Google spreadsheet using the Script Editor, I do function calls, but I am not quite sure if the best way to store persistant data (data that I will continue to use) is to use global variables (using objects, arrays, strings), or there is a better way to store data.
I don't want to use cells which could be another way.
Another question, is it possible to create (pseudo) classes in this environment? Best way?
Both ScriptProperties and ScriptDB are deprecated.
Instead, you should be using the new class PropertiesService which is split into three sections of narrowing scope:
Document - Gets a property store that all users can access within the current document, if the script is published as an add-on.
Script - Gets a property store that all users can access, but only within this script.
User - Gets a property store that only the current user can access, and only within this script.
Here's an example persisting a user property across calls:
var properties = PropertiesService.getScriptProperties();
function saveValue(lastDate) {
properties.setProperty('lastCalled', lastDate);
}
function getValue() {
return properties.getProperty('lastCalled');
}
The script execution environment is stateless, so you cannot access local variables from previous runs, but you can store getScriptProperties() in a local variable because it will be re-run for each return trip to the server so it can be called in either method.
If you need to store something on a more temporary basis, you can use the CacheService API
Persistent data can be stored using the Class ScriptProperties:
http://code.google.com/googleapps/appsscript/class_scriptproperties.html
All values are stored as a string and will have to be converted back with the likes or parsInt or parseFloat when they are retrieved.
JSON objects can also be stored in this manner.
My experience has been that every query to retrieve or store values takes a long time. At the very least, I would cache the information in your javascript code as much as possible when it is safe. My scripts always execute all at once, so I don't need to keep global variables as I simply pass the retrieved data arrays around, manipulate them, and finally store them back in one fell swoop. If I needed persistence across script invocations and I didn't care about dropping intermediate values on close of the webpage, then I'd use globals. Clearly you have to think about what happens if your script is stopped in the middle and you haven't yet stored the values back to Google.

Using the Google geolocation object as a session var

I'm building an app which needs to know where the user is; it displays events within a radius of the user.
I'm using the Google geocoding API and have been saving the returned object as a session variable and passing the info to and fro using ajax to retrieve and update the location.
I've noticed that occasionally the array and object keys will be different. For instance, sometimes it will have a nicely formatted results.geometry.location.lat hierarchy, but then occasionally it will be results.geometry.location.d and sometimes even results.geometry.location.A.
I created a getter in javascript which will return the lat and lng regardless of the keys returned. I'm surprised that the returned objects don't have built in getter functions when the array keys vary like that.
So, I'm wondering if there's a better way to store the user's location than just saving the entire geolocation response. I tried paring it down to just what I want to use, but that means every time I make a call to Google for a location, I need to process it.
Has anyone had any experience getting this sort of thing to work?
Thanks
EDIT:
I'm using cakePHP and I realized I should have made this a datasource from the get-go. I currently have all the logic in a component being called from my controllers. I'm going to spend some time creating a datasource, which should take care of the getting and setting of this mutating object.

underscore isEqual and JSON

I have a question using underscore isEqual to compare two JSON strings. Currently i have done an app in backbone, and I'm using _.isEqual(savedModel.toJSON(),changedModel.toJSON() ) to detect if the model has changed in the page and promt a "You have unsaved changes, do you want to save?" dialog if the user tires to navigate away.
For some reason I get the dialog in random places even though I have done nothing or have saved changes. Debugging is driving me crazy.
Could this be because JSON does not guarantee the order of the objects in the JSON and underscores isEqual does not handle this case properly? So even if the models are the same, some attributes in the JSON might be different and it returns false?
Pseudocode:
//when entering the page the original model is cloned, when user does changes to the
//page, the model is cloned again
var savedModel = currentModel.clone().toJSON();
//when the user tries to navigate away from the page
if( _.isEqual(savedModel, model.toJSON() ){
showSavePromptDialog();
}
Following the chain of functions used by backbone.toJSON(), it appears _.extend is used to copy the object and _.extend uses a for..in loop to iterate over the object. for..in iterates over an object in arbitrary order, which is likely the source of your problem.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
Hi this deep equals implementation done to solve similar problem, but I might have missed out some finer details, it was serving well for my purpose.
http://yui3.wordpress.com/2013/04/22/deep-compare-in-javascript/

Monitor changes to an array

I'm using a third party javascript library in my application and I need to be able to monitor a particular array property for changes. So for example, the third party library adds an object to widget.loadingQueue anytime a widget is being loaded. I want to be able to monitor this property and display a loading indicator anytime there are elements in the array. The library is open source, but if possible I'd like to do this without having to go through their source and find every time they add something to the array and add in a method call.
If they add to the array by calling push(), you can simply create a custom push() method on the array that runs your handling code and calls Array.prototype.push().
This is how Google Analytics' _gaq array works.

When and how does Asynchronous Google Analytics execute?

I'm switching over our site to use Asynchronous Google Analytics, and I'm curious about it's method of pushing events to the _gaq array. Near as I can tell, events are placed into a waiting pattern in _gaq while the ga.js script is being asynchronously downloaded. Do they fire once the script is downloaded, and how are post-document load events tracked?
One example is a user clicking a link 10 seconds after page load - according to documentation the event should be placed into the _gaq. How does the analytics script detect this?
The general part is best described by the Google Analytics Async doc.
To push an API call onto the queue, you must convert it from the traditional JavaScript syntax into a command array. Command arrays are simply JavaScript arrays that conform to a certain format. The first element in a command array is the name of the tracker object method you want to call. It must be a string. The rest of the elements are the arguments you want to pass to the tracker object method. These can be any JavaScript value.
I'll try to explain the juicy details:
_gaq is just a plain JavaScript Array, and all arrays have the push method to add an entry to the end of the array. So before the Analytics script is loaded, all commands will be pushed to the array. At the end of the Analytics script, it replaces the _gaq.push method with a custom method and executes all entries in the _gaq array. The new _gaq.push method will run the tracking method instantly. So when you run the push method 10 seconds after page load, the command should be executed.
It's always difficult to un-obfuscate the google analytics code, but if I were to solve this problem, upon loading the script, I would redefine the push function on the array after processing everything in the backlog queue (_gaq). This way, the redefined push function would simply act as a proxy to the actual function calls on the pageTracker object.
Here's a simple example of redefining the push method on an array object:
var foo = [];
foo.push("one"); // pushes "one" onto the array
foo.push("two"); // pushes "two" onto the array
foo.push = function(a) { alert(a) }; // redefines `push`
foo.push("three"); // alerts "three"
alert(foo); // alerts "one,two"

Categories