Creating Custom Components

Overview

The Embed API comes with several built-in components and also gives you an easy way create your own. This document explains how to build a new custom component and how to include third-party components in your application.

Creating a custom component

Custom Embed API components are created by calling gapi.analytics.createComponent and passing a component name and methods object.

The name passed to createComponent will be the name of the component's constructor function, and it will be stored on gapi.analytics.ext. The methods object should contain any functions or properties you want added to the component's prototype.

gapi.analytics.createComponent('MyComponent', {
  execute: function() {
    alert('I have been executed!');
  }
});

Once the component is created, it can be used by calling the new operator with the component constructor.

// Create a new instance of MyComponent.
var myComponentInstance = new gapi.analytics.ext.MyComponent();

// Invoke the `execute` method.
myComponentInstance.execute() // Alerts "I have been executed!"

The initialize method

Passing a methods object to createComponent gives you access to your component's prototype, but it doesn't give you access to your component's constructor.

To address this issue, when new Embed API components are created, they will automatically look for the presence of a method called initialize. If found, it will be invoked with the same arguments passed to the constructor. All logic that you'd normally put in a constructor should be put in the initialize method instead.

Here is an example that sets some default properties when new MyComponent instances are created.

gapi.analytics.createComponent('MyComponent', {
  initialize: function(options) {
    this.name = options.name;
    this.isRendered = false;
  }
});

var myComponentInstance = new gapi.analytics.ext.MyComponent({name: 'John'});
alert(myComponentInstance.name); // Alerts "John"
alert(myComponentInstance.isRendered); // Alerts false

Inherited methods

Components created with the createComponent method will automatically inherit the base methods shared by all built-in components (get, set, on, once, off, emit). This ensures all components work in a consistent and predictable way.

For example, if your component requires the user to be authorized, this can be accomplished using the inherited event handling methods.

gapi.analytics.createComponent('MyComponent', {
  initialize: function() {
    this.isRendered = false;
  },
  execute: function() {
    if (gapi.analytics.auth.isAuthorized()) {
      this.render();
    }
    else {
      gapi.analytics.auth.once('success', this.render.bind(this));
    }
  },
  render: function() {
    if (this.isRendered == false) {

      // Render this component...

      this.isRendered = true;
      this.emit('render');
    }
  }
});

var myComponentInstance = new gapi.analytics.ext.MyComponent();

// Calling execute here will delay rendering until after
// the user has been successfully authorized.
myComponentInstance.execute();
myComponentInstance.on('render', function() {
  // Do something when the component renders.
});

Waiting until the library is ready

The Embed API snippet loads the library and all of its dependencies asynchronously. This means that methods like createComponent will not be available immediately, and code that invokes such methods must be deferred until everything is loaded.

The Embed API provides the gapi.analytics.ready method that accepts a callback to be invoked when the library is fully loaded. When creating custom components, you should always wrap your code inside the ready function so it doesn't run before all required methods exists.

gapi.analytics.ready(function() {

  // This code will not run until the Embed API is fully loaded.
  gapi.analytics.createComponent('MyComponent', {
    execute: function() {
      // ...
    }
  });
});

Using third-party components

Third party Embed API components are typically packaged as individual JavaScript files that you can include on your page using a <script> tag.

Load order matters, so it's important to include the Embed API snippet first, followed your component scripts and any of their dependencies.

<!-- Include the Embed API snippet first. -->
<script>
(function(w,d,s,g,js,fjs){
  g=w.gapi||(w.gapi={});g.analytics={q:[],ready:function(cb){this.q.push(cb)}};
  js=d.createElement(s);fjs=d.getElementsByTagName(s)[0];
  js.src='https://apis.google.com/js/platform.js';
  fjs.parentNode.insertBefore(js,fjs);js.onload=function(){g.load('analytics')};
}(window,document,'script'));
</script>
<!-- Then include your components. -->
<script src="path/to/component.js"></script>
<script src="path/to/another-component.js"></script>

Managing dependencies

A component may have dependencies such as a charting library like d3.js or a date formatting library like moment.js. It is up to the component author to document these dependencies and up to the component user to ensure these dependencies are met.