Veyo Technology: Incorporating Segment in an Angular App

December 27, 2017

Using Angular Environments to Configure Multiple Segment Sources

We say we love technology, and we mean it! Our tech team is obsessed with anything techy. Artificial intelligence, virtual reality, autonomous vehicles, the latest apps (and phones)…if it’s cool and new, you can bet they know all about it. And while they’re working on new and better ways to improve patient transportation, they’re also documenting new and improved ways to streamline everyday processes. In a new series we’re launching, we’re asking our tech team to share some of their new discoveries and processes, in hopes that we can inspire some tech breakthroughs outside of Veyo. These posts are pretty tech heavy, but we’ll try to give you a quick overview in non-tech language before we dive in.

For this post (brought to you by AJ Zane, one of our Front End Engineers) we’ll be discussing how to track how users interact with your app using a tool called Segment. Why track user interactions?  Tracking means data, and data means better decisions and a better user experience. Why guess which layout your users like better if you can test which layout users like better.

——-

In an ideal web project, every feature should be developed because you have proof that it will make your app better for the user. At Veyo, as soon as a new feature launches, we start gathering data on it so we can make educated and objective decisions about how to adapt it.

In this article, I’m going to show you how we added event tracking into our Angular GUIs so you can start tracking how users interact with your app and begin making objective decisions about what to build next.

Segment

If you haven’t had the pleasure of working with Segment, you can think of it as an analytics piping tool. It doesn’t have visualization tools, querying features, and it only stores your data for a limited time. All so that Segment pushes you to use its service as little as possible – great business model, huh?

Seriously, though, Segment takes the stream of your data and pipes it to other services. For example, if today you’re using Google Analytics, you can switch to MixPanel tomorrow by simply changing where Segment will pipe your data. You won’t have to update any code to work with the new API. This means you can easily pivot to changing business needs without having to wait on engineers. In fact anyone who can use the Segment dashboard can change their services without bugging an engineer at all.

Getting started with Segment is a cinche: It’s all point and click. Once you go through the setup process, you’ll get your analytics key. Keep this for later.

Add Angulartics (simple)

Angulartics is very similar to Segment in that it’s the kind of tool that tries to say out of the way as much as possible. Just like Segment, it has a single API that you configure to choose which service to send the data to. If your business needs change, with a few lines of configuration code you can start passing your data to a completely different analytics tool.

Add the angulartics package through NPM:

npm i --save angulartics2

Import it into your app (app.module.ts):

import {
  Angulartics2Module,
  Angulartics2Segment,
} from 'angulartics2'

@NgModule({
  imports: [
   Angulartics2Module.forRoot([ Angulartics2Segment ]),
  ]
})

Include the snippet in index.html

NOTE: This snippet may be out of date. Make sure you copy the code from your Segment account when you set it up

<script type="text/javascript">
  !function(){var analytics=window.analytics=window.analytics||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","once","off","on"];analytics.factory=function(t){return function(){var e=Array.prototype.slice.call(arguments);e.unshift(t);analytics.push(e);return analytics}};for(var t=0;t<analytics.methods.length;t++){var e=analytics.methods[t];analytics[e]=analytics.factory(e)}analytics.load=function(t){var e=document.createElement("script");e.type="text/javascript";e.async=!0;e.src=("https:"===document.location.protocol?"https://":"http://")+"cdn.segment.com/analytics.js/v1/"+t+"/analytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(e,n)};analytics.SNIPPET_VERSION="4.0.0";
  analytics.load("...your analytics key goes here...");
  analytics.page();
  }}();
</script>

(NOTE: The `analytics.load()` method takes in your Segment Source’s key)

Use it in your code:

import { Angulartics2Segment } from 'angulartics2'

@Injectable()
export class MyService {
 constructor(protected analytics: Angulartics2Segment) { }
 someMethod() {
   this.analytics.eventTrack(‘action’, { customProps: ‘value’, metaProps: ‘value’ })
 }
}

Now, this works but has a few big issues:

  1. The entire app now knows about analytics – which might not be required
    1. I like keeping my feature modules self contained so I can drop them into other projects if needed. If the analytics method is defined at the App level, my feature module will be able to use it in this project, but break in another project that doesn’t use Angulartics
  2. The snippet in the index file would be easier to maintain in a separate script, instead of part of index.html.
    1. Separating concerns is good, so we should do that
  3. Load angulartics in main.ts instead of index.html
    1. You should only track analytic events in production. AngularCli’s environment configuration lets us easily set the analytics key so that it’s only applied in certain environments (I’ll write about this in another article)
    2. If there is no key, Segment will fail non-fatally and your app will keep working
  4. Register unique users with `identify()`
    1. This is very important if you want to make sure you don’t hit Segment’s Monthly Tracked User limit. If you forget to identify the user, every page visit will count as a new user
  5. Consider creating a personalized analytics service
    1. Your app probably has some very repetitive actions you will want to track like Button Clicks. It’s much easier to make a class (say, `buttonClickEvent`) that only takes in which button was clicked. This way, you will write less code each time you use the button click event, and you’ll be able to refactor the event in one location, instead of across the entire app. You can also append other data to your analytics, for example a User Type. The service can manage this variable, instead of requiring all of your components tracking and sending this data.
    2. You can feel comfortable in calling its APIs even if the method of sending analytics events changes. Just like Segment is great because you can plug in other tools, you app shouldn’t care that it’s using Angulartics and Segment – it just needs to pass data.

Add Angulartics (Advanced)

I’ve setup a sample project that covers some of the extra use cases in the previous section. I invite you to take a look at the commits to see how I modified the application to be more configurable.

Dependency on the router

Currently, Angulartics has a requirement on the Angular router. If your app is not using the router, you will have a non-fatal console error. Hopefully this will get resolved soon (Pull Request, anyone??)

You can follow the progress of this issue, and find some workarounds in these links:

Conclusion

I hope this article will help you start adding analytics to your apps today. Now that your app is sending data to Segment, you can pipe it to other services such as Google Analytics to start analyzing your data. Stay tuned for my next article, where I’ll dive into creating that connection.

– AJ Zane, Front End Engineer at Veyo

Part 2: Using Angular Environments to Configure Multiple Segment Sources

Part 3: Connecting Segment to Google Analytics

Want to Join Our Tech Team?

Find our open positions here.