Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to use Optimizely (or other DOM manipulating A/B testing tools) on a site using Angularjs?

I am looking to use Optimizely on a site where we will use Angularjs, but from what I understand, that will be difficult because the whole purpose of Angularjs is to not manipulate the DOM, and Optimizely works by manipulating the DOM.

Does anyone have any guidance toward documents as to how to make using these tools together possible? Perhaps a structure where I could create directives to help the tool work?

like image 426
Tyler Riggs Avatar asked Feb 20 '14 23:02

Tyler Riggs


3 Answers

First, you need to make the "Activation Mode" of the experiment "Manual".

Then, to make Optimizely check if the experiment should run (ie meets the URL target) you need to call window.optimizely.push(["activate"]). This tells Optimizely to do the same thing it would do on a normal full page load. So depending on your situation, you can call the optimizely api from a few different locations...

In the run method of the app when views load

This works when what your experiment changes isn't tied to dynamic pieces that angular might make after the view loads. The $routeChangeSuccess event won't work with activating Optimizely because it fires before there's any DOM to manipulate.

app.run(function run($rootScope){
    $rootScope.$on('$viewContentLoaded', function() {
        window.optimizely = window.optimizely || [];
        window.optimizely.push(["activate"]);
    });
});

A more explicit way is to call window.optimizely.push(["activate"]) just in the controllers or directives that will actually have experiments. This way you can control the exact timing of the activate, like after data is loaded. I prefer this method because, more often than not, you're going to have to call the optimizely API to log a custom event to log that the user completed the desired goal anyway, so if I'm doing that event tracking explicitly, I might as well activate optimizely explicitly. Here's a service I inject when I need to activate or log events...

(function () {
    'use strict';

    function Optimizely($window) {
        $window.optimizely = $window.optimizely || [];

        this.Activate = function () {
            $window.optimizely.push(["activate"]);
        };

        this.TrackEvent = function (eventName) {
            $window.optimizely.push(["trackEvent", eventName]);
        };
    }

    angular.module('myApp').service('Optimizely', Optimizely);
}());

Usage in a controller...

function MyCtrl(Optimizely) {
    Optimizely.Activate();
    Optimizely.TrackEvent("my_goal_success");
}
like image 125
JeremyWeir Avatar answered Oct 30 '22 03:10

JeremyWeir


Yes, but you'll need to use the Optimizely's Javascript API.

http://developers.optimizely.com/javascript/

For anything more in depth you could also look at doing your own bucketing and using custom dimensions

Own Bucketing Example: https://github.com/tomfuertes/gaab

Custom Dimensions Docs: https://support.google.com/analytics/answer/2709829?hl=en

Edit:

On a high level Optimizely is a front end abstraction to a system that buckets and manipulates the DOM. It's meant to be used by non-devs or devs who want to use the reporting piece. You can still get to the same thing if you're custom coding an angular app by writing your own bucketing, splits, and features with a separate analytics tool like GA. Sounds daunting but is fairly simple if you take a look at the gaab sample code above.

like image 42
TomFuertes Avatar answered Oct 30 '22 04:10

TomFuertes


I'm not sure how Optimizely works, but with Visual Website Optimizer there is a feature that allows us to add a variation using JS. We manipulate the content like so:

// get Angular scope from a known DOM element
e = document.getElementById('some-dom-id');
scope = angular.element(e).scope();
// update the model with a wrap in $apply(fn) which will refresh the view for us
scope.$apply(function() {
    scope.campaign.headline = 'This is a headline.';
}); 
like image 21
timelf123 Avatar answered Oct 30 '22 03:10

timelf123