Rich-text Reply

Experiment activate callback

guilhermef 12-05-14

Experiment activate callback

I've been struggling with the activate method.

Since it does an ajax request to fetch which experiments are running, I couldn't find a way to lazy load the optimizely script, and run my code with the current variation.

 

window.optimizely.push(["activate", xxxxxxx]);
var experimentID = window['optimizely'].data.state.activeExperiments[0];
variation = window['optimizely'].data.state.variationNamesMap[experimentID];

 

this code doesn't guarantee I'll have the current variation.

 

I thought I could do something like:

 

window.optimizely.push(["activate", xxxxxxx, function(variation){

  mycode(variation);

}]);

 

thanks Smiley Wink

 

 

Shaunak 12-08-14
 

Re: Experiment activate callback

Hi,

The problem here is due to the fact that the Optimizely snippet is being lazy loaded. It is important that Optimizely is loaded in the head tag and as high as possible, because the way Optimizely works is by modifying the elements before the user can see them.

In your case, the way Optimizely would identify active experiments is via a javascript object and not an ajax call. If the snippet is lazy loaded the object might not exist and the activate function will fail.

Is there a reason you are trying to lazy load the snippet?
Optimizely
guilhermef 12-10-14
 

Re: Experiment activate callback

I'm lazy loading the script, because we're only testing on small screens.
So this way I avoid the impact of loading an external script to all users.

Since we're a huge portal, we always avoid unnecessary requests to the end user.

I'm including the script, and after it's loaded I'll call the onload callback.

the full snippet looks like this:

$.getScript('//cdn.optimizely.com/js/xxxxx.js').done(function(){
window.optimizely.push(["activate", xxxxxxx]);
var experimentID = window['optimizely'].data.state.activeExperiments[0];
variation = window['optimizely'].data.state.variationNamesMap[experimentID];
document.body.className += variation;
})

this guarantees the optimizely object, but sometimes I get an undefined from the state object.
I've assumed that the state hadn't been loaded.
Is that right ?
guilhermef 12-22-14
 

Re: Experiment activate callback

Any thoughts about this ?

Should I give up and search for a better tool ?

Shaunak 01-26-15
 

Re: Experiment activate callback

Hey GUILHERMEF
 
You're correct that this method should guarantee the window.optimizely object to be defined.
 
The `.done` promise invoked by the $.ajax call will not execute until the downloaded script has, meaning any synchronous code in the Optimizely snippet (which includes extending the data object into window.optimizely), should happen before the promise executes.
 
I just tested this myself and cannot reproduce an error with the state object being undefined (using jQuery 1.9.1).
 
Are you able to reproduce this? If so, what version of jQuery and which browser are you using?
 
In any case, if the promise is executing before Optimizely is, you can pretty simply wrap your execution code inside an interval to wait until it is safe to run.
 
 
```
var experimentCode = function() {
  window.optimizely.push(["activate", xxxxxxx]);
  var experimentID = window['optimizely'].data.state.activeExperiments[0];
  variation = window['optimizely'].data.state.variationNamesMap[experimentID];
  document.body.className += variation;
};
var pollForReady = function() {
  if (window.optimizely.data.state) {
    experimentCode();
  }
  else {
    setTimeout(pollForReady, 50);
  }
};
  .done(pollForReady);
```
Optimizely
guilhermef 02-02-15
 

Re: Experiment activate callback

SHAUNAK,
that would work, but since the nature of javascript is asynchronous it would be wiser to use some kind of callback.

It's better to have optimizely calling some function than waiting for it to be populated.
On this solution if any error occur inside optimizely, I would end up with a function being called every 50 ms forever.

Why can't we have this:

window.optimizely.push(["activate", xxxxxxx, function(variation){
experimentCode(variation);
}]);

I've already implemented an array like callback, that mimics a lot the _gaq behavior.
It's the best way to deal with asynchronous code.
I could share the code with you.
What do you think ?
guilhermef 02-04-15
 

Re: Experiment activate callback

SHAUNAK,
I've created a lib to Optimizely.

https://github.com/guilhermef/optimizely-ab-callback

It can be used to achieve experiment callbacks after the state is loaded.
Shaunak 02-09-15
 

Re: Experiment activate callback

Thanks for posting this ! Let us know if you run into any issues, given the asynchronous nature of the javascript !
Optimizely
dr_gustavo 03-05-15
 

Re: Experiment activate callback

It's really a shame this isn't implemented natively on optimizely, can we know if this is in the roadmap at least?