5

We are working on a very large codebase. It's basically a web-based operating system, with its own file system and applications. The system's UIs are generated dynamically with Javascript.

We've decided to introduce Google Analytics to track various user activities.

Our concern is that in order to send data to Google Analytics servers on these events we'd have to scatter analytics code in all event handlers. Even if we wrap the analytics calls in a module, we'd still have to call it. E.g. usual code:

$(importButton).on('click', function() {
    // ... call import module to do import stuff
})

becomes, roughly speaking

$(importButton).on('click', function() {
    // ... call import module to do import stuff
    analytics.registerEvent('import')
})

And so the analytics code becomes extremely tightly coupled to the interface logic.

How do we introduce analytics in a modular fashion, without scattering analytics calls over all event handler functions?

gnat
  • 21,442
  • 29
  • 112
  • 288
Stas Bichenko
  • 3,689
  • 4
  • 24
  • 32
  • 2
    Replace `.on` with a function that registers the handler but also calls analytics behind the scenes? – Doval Nov 20 '14 at 15:30
  • @Doval that's ill advised unless you need mocking. Since most of the time this additional functionality won't be needed anyways, that's just additional cost of calling a mocked method. – scriptin Nov 20 '14 at 18:22

1 Answers1

4

You don't have to change existing code, because you can just add more event handlers. JavaScript naturally supports multiple event handlers on a single element, and it's even easier with libs/frameworks like jQuery:

// in existing code:
$('#button').on('click', function (event) {
    console.log('normal behavior');
});

// somewhere else:
$('#button').on('click', function (event) {
    console.log('user tracking');
});

This does not affect performance significantly and you can always improve it with event delegation.

scriptin
  • 4,432
  • 21
  • 32
  • 1
    What if the button's function depends on outside conditions? For example, a "Create new" button may create different types of files depending on a menu setting. – Stas Bichenko Nov 21 '14 at 10:05
  • If possible, event should occur on concrete action, or be composed of several simple events: e.g. "button clicked" followed by "window opened". That fits a definition of [goal](https://support.google.com/analytics/answer/1012040?hl=en). Also you can check those outside conditions the same way as in existing code. If, however, you need something more complex, you'd have to modify you code anyway to produce some kind of custom events with additional state. In that case, you'd have to modify your code anyway, and I don't think there is a way to avoid that. Complex problems have complex solutions. – scriptin Nov 21 '14 at 18:07