Trials and Tribulations in the Wild World of Web Analytics

Waiting for Godot

Once upon a time, I faced a situation where a web application relied upon custom link tracking heavily. Unfortunately, the application could send tracking values before the s_code loaded.

While I doubt this occurs too often, I think there is value in this example. Such as the future posts I have planned which use this example as a component. Finally, if the code looks a bit odd, its a modified version of the JavaScript Module Pattern.

Implementation, Live Example, Example Code:

Utilizing the tracking buffer is fairly simple, the earlyTracking function can stand alone. However, for an implementation without modifying the earlyTracking function, three things are required.

  • objTrackingVariables and trackData are required
  • Custom link tracking to be buffered must use trackData()
  • sendTracking() within trackData() must be configured to send data to Omniture

Try the Example or See the Code from the Example

Breaking Down the Code:

First, an object to put everything in and keep things clean.
var customTrack = {};
Next an object to keep variables we want to persist. Some parts are for future posts.
customTrack.objTrackingVariables = {
    strInteractTrackVars: 'props, eVars, events',
    blnBufferOn: false,
    blnLoadFail: false,
    arrTrackingArray: []
};
Expanding this part in future posts.
customTrack.trackData = (function () {

    //Expanding on this part later

    function sendTracking(strTrackType, strTrackValue){

    //tracking is prepared then sent here

    }

    return function (strTrackType, strTrackValue) {
        if ('undefined' !== typeof(s) && !customTrack.objTrackingVariables.blnBufferOn) {
            sendTracking(String(strTrackType), String(strTrackValue));
        } else if (!customTrack.objTrackingVariables.blnLoadFail) {
            customTrack.earlyTracking(String(strTrackType), String(strTrackValue));
        }
    };
}());
The fun for this post starts here.
customTrack.earlyTracking = (function () {
Creating a object to hold values we want to persist, and only accessible inside the earlyTracking function.
    var objEarlyBuffer = {
        blnDataStored: false,
        blnIntervalOn: false,
        intIntervalCounter: 0,
        arrEarlyArray: [],
        intervalCheckS: null
    };
This function sends the tracking values we have stored in the ‘buffer’ array.
    function sendEarlyTracking() {
        var intEarlyBufferCounter = -1;
        var arrTrackLink = [];
        while (++intEarlyBufferCounter < objEarlyBuffer.arrEarlyArray.length) {
            arrTrackLink = String(objEarlyBuffer.arrEarlyArray[intEarlyBufferCounter]).split("|");
            customTrack.TrackData(String(arrTrackLink[0]), String(arrTrackLink[1]));
        }
        objEarlyBuffer.blnDataStored = false;
        objEarlyBuffer.arrEarlyArray = [];
        objEarlyBuffer.blnIntervalOn = false;
        if ('undefind' !== typeof(customTrack.objTrackingVariables.blnBufferOn)) {
            customTrack.objTrackingVariables.blnBufferOn = false;
        }
        clearInterval(objEarlyBuffer.intervalCheckS);
    }
After the 100ms interval is created (next function), this function checks if ‘s’ is defined and clears the interval after two minutes if ‘s’ is not seen.
    function sReady() {
        objEarlyBuffer.intIntervalCounter++;
        if (objEarlyBuffer.blnIntervalOn && objEarlyBuffer.intIntervalCounter > 1200) {
            clearInterval(objEarlyBuffer.intervalCheckS);
            objEarlyBuffer.blnIntervalOn = false;
            customTrack.objOmniVars.blnBufferOn = false;
            customTrack.objOmniVars.blnLoadFail = true;
        }

        if (objEarlyBuffer.blnIntervalOn && 'undefined' !== typeof(s)) {
            clearInterval(objEarlyBuffer.intervalCheckS);
            objEarlyBuffer.blnIntervalOn = false;
            if ('undefind' !== typeof(customTrack.objTrackingVariables.blnBufferOn)) {
                customTrack.objTrackingVariables.blnBufferOn = false;
            }
            sendEarlyTracking();
        } else {
            return false;
        }
    }
Below is the functionality for the ‘public’ method.
    function bufferEarlyTracking(strTmpTrackString) {
        if (!objEarlyBuffer.blnIntervalOn) {
            if ('undefind' !== typeof(customTrack.objTrackingVariables.blnBufferOn)) {
                customTrack.objTrackingVariables.blnBufferOn = false;
            }
            objEarlyBuffer.blnIntervalOn = true;
            objEarlyBuffer.intervalCheckS = setInterval(sReady, 100);
        }
        objEarlyBuffer.blnDataStored = true;
        objEarlyBuffer.arrEarlyArray.push(strTmpTrackString);
        if ('undefined' !== typeof(s) && objEarlyBuffer.arrEarlyArray.length > 0 && !objEarlyBuffer.blnIntervalOn) {
            sendEarlyTracking();
        }
    }
Wrapping things up.
    return function (strTrackType, strTrackValue) {
        bufferEarlyTracking(String(strTrackType) + "|" + String(strTrackValue));
    };
}());

More to Come. Comments Encourage.

NO COMMENTS