Event Tracking in Ember - Architecture best practices


#1

I have an app that requires both some passive and active event tracking. In general, I have a main Controller, but haven’t yet put much logic into a View yet. When users interact with the interface, I want track these types of events:

  1. page views (active)
  2. votes (active)
  3. time spent on the page (passive) etc…

I want these events to be passed on to a tracking API using traditional POST requests. I’m confused as to where to put this logic. I have the inclination to keep tracking logic separate from my main user experience since it seems like an isolated function, but then I don’t want to give a reusable component (like analytics tracking) too much control. Also, I’m not sure if this should be another controller, and if so, how best to implement. Further, should all communications with the server generally be grouped together so that the Tracker utilizes a “Utils” or something?

Any advice on how to best separate function and utility in an ember app? Thanks so much!


#2

Look into using didTransition on the router. You can add your logging/eventing and restart timer logic each time that action is triggered. This would solve 1 and 3.

Votes… I have no idea what that is.

var Router = Ember.Router.extend({
    logTransition: function() {
        /* note: there is probably a better way to get the routeName such as grabbing it off the application controllers currentPath property. */
        var routeName = this.get('router.state.handlerInfos.lastObject.handler.routeName');

        someLoggingApi({ route: routeName });
    }.on('didTransition')
});

Demo: http://jsfiddle.net/NQKvy/1080/


#3

Hi Jason -

Thanks very much! So regarding the “Votes” context, there is a controller that handles a Poll, and when a user votes, we want to track it. I find myself wanting to avoid putting that type of tracking in a Router, and don’t want to make a component, per se, as it isn’t specifically related to a DOM element. (The link that is clicked will be a component that fires off an event). I’d really like to have a Tracking Controller, but don’t know how to plug that into a Poll Controller. Does that make sense?


#4

http://jsfiddle.net/NQKvy/1121/


#5

ok, that’s about perfect! Thanks so much Jason. I really appreciate your thorough help.


#6

Good to hear, glad I could help :slight_smile:


#7

Hi Jason -

Ok, I’m almost there. As it turns out, we have an object (our controller’s model) that is fairly complicated. We need to access just one attribute on that model, which is an array, but yet doesn’t work the way I thought it would. I adapted your JSFiddle as an example. Any pointers would help tremendously! http://jsfiddle.net/NQKvy/1133/

Thanks again!


#8

@panzhuli I don’t see the changes to the fiddle you’re referring to. I’m not sure what you’re using as your model, is this an ember-data model with a hasMany relationship?


#9

Bummer - It looks like I didn’t save it properly. The model is an object, something like:

FIXTURE = {
title: "ember can be challenging!",
list: [ {foo: "bar"}, {foo: "bar"}, {foo: "bar"}]
}

but when I iterate through the model.list, like this:

  {{#each model.list}}
    {{#each itemController='pollItem'}}
      foo bar 
    {{/each}}  
  {{/each}}

I receive an Assertion Failed: ArrayProxy expects an Array or Ember.ArrayProxy, but you passed object error

Here’s another link, hoping it works for you. http://jsfiddle.net/NQKvy/1145/


#10

The problem is you’re attempting to enumerate over POJOs, when I think you just want to enumerate over the model.list items and make each item backed by its own pollItem controller.

http://jsfiddle.net/NQKvy/1146/


#11

@jasonmit - wow, that was embarrassingly easy. Thanks again for helping me work through it all