TinCanAPI.co.uk

Helping you Tin Can since 2012.

Build your first Tin Can API activity

Tin Can specification version: 1.0.0

This guide will take you through the process of creating your first Tin Can API activity. The specific activity you will create is one that allows the user to search for a book on Google books and then send a statement to an LRS saying that they have "experienced" the book. You can get the full version of the code that this tutorial is based on here.

Ideally you need to have an understanding of HTML, CSS and JavaScript before attempting this tutorial. Give it a go anyway even if you're a beginner to these things, or look up some beginner's html, css and JavaScript tutorials on the interweb - there's plenty out there. The tutorial also makes use of JQuery and the Google Books API but there's no requirement to understand these so long as you are competent at copying and pasting.

Please note: The application discussed in this tutorial will not work with Internet Explorer 9 or below. Please use Firefox or Chrome.

Feel free to ask about any aspect of this tutorial at all on Twitter @mrdownes or by email to mrdownes@hotmail.com

Contents

 [hide

HTML file

Let's start with the HTML file. This essentially just contains the basic structure of the page and there's not a lot that's Tin Can specific here. You can get the full copy of the html file here, but I'll go through the only section relevant to Tin Can here - the script references.

Script references

This section of the HTML provides links to various JavaScript libraries or files. Let's take each of them in turn and explain what they are and why they are included.

  1. JQuery - I tend to include the JQuery library in all my web projects, Tin Can or otherwise. Jquery.com describes Jquery as "jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript." Basically it's a code library that makes a lot things easier to do than if you were just using pure JavaScript. Finding, adding and changing elements on the page are some of the core things that JQuery is really helpful for, and that's what we use it for in this tutorial.
  2. TinCan.js - The Tin Can Driver file take from Rustici Software's Github. This file is released under an Apache 2.0 License and does a lot of the complicated aspects of Tin Can API for you. It's still under development and I had to make a couple of fixes to get this tutorial to work, but I've shared these fixes with the Rustici guys so hopefully they'll be included in the latest version by the time you read this guide and download the code. If not, you can just pinch my copy of the code here.
  3. Base64 - a 3rd party code library used for encryption of the users LRS account details. I originally got this file from Rustici's Tin Can 0.90 prototypes, but you can get it from my Github site.
  4. TinBook.js - the JavaScript file containing the code specific to this activity. This tutorial will take you through writing this JavaScript file for yourself.


<!-- jquery  -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
 
<!-- tincan.js - Rustici's Tin Can API JS Client Library-->
<script src="tincan.js"></script>
 
<!-- Base64 -->
<script src="base64.js"></script>
 
<!-- TinBook.js - main code file for the activity -->
<script src="TinBook.js"></script>

TinBook.js

The JavaScript files are where the magic really happens. Let's look at the Tin Can specific sections of the TinBook.js code.

Setting up the LRS connection

This part of the tutorial differs significantly from my 0.90 version of this tutorial, not really because of significant changes in the spec, but more related to changes in the way Rustici's Tin Can library works.

The first thing we need to do is create an instance of the TinCan object. You can set various properties when creating this, but I'm just going to stick with the defaults for this tutorial. Let's call our instance myTinCan:

var myTinCan = new TinCan();

Now we need to create an instance of the TinCan LRS Object. This time we do want to define some of the properties and we do this by passing an annoymous object like so:

var myLRS = new TinCan.LRS({
	endpoint:"https://cloud.scorm.com/ScormEngineInterface/TCAPI/public/", 
	version: "1.0.0",
	auth: 'Basic ' + Base64.encode("<account id>" + ':' + "<password>")
});

You can see here we are defining the endpoint, target version and authorisation credentials for this particular LRS. Why don't you try your own details from your SCORM Cloud, Watershed or Wax LRS account here?

Next we need to add the LRS to the array of record stores being targeted by our TinCan object:

myTinCan.recordStores[0] = myLRS;

For this tutorial we are just going to fire statements at one LRS, but you can set the TinCan object to send copies of your statements to multiple LRS if you prefer. You would simply define additional LRS and add them sequentially to the array.

Finally, lets define our default actor and add him to the actor property of our TinCan object:

var myActor = new TinCan.Agent({
	name : "Bob Smith",
	mbox : "mailto:dummy@example.com"
});
 
myTinCan.actor = myActor;

Note that the actor is a type of agent, and uses the Tin Can library's agent object.

In this example the endpoint, authorisation details and actor details are all hard coded. In a real application of course you would want to get this data from the user in some way and the TinCan library includes methods for getting this data via query string if that's your preference.

The next section of code that deals with some interface stuff and getting the book data from the Google Books API. As this is not directly related to Tin Can, I'm going to skip it for this tutorial. You can just copy and paste this section from my GitHub.

Send a Tin Can API Statement

This line of code declares an object called 'item'. This object contains the information about the book the user selected and will be used to pull data from in order to build the Tin Can statement. The Tin Can code starts again immediately 'after' this line.

var item = response.items[$('.bookElement').index($(this).parent('div'))];

Verb

First we declare a verb object defining the relevant properties. Note how the display property itself contains an object defining the display value of the verb in both American English and British English.

	var myVerb = new TinCan.Verb({
		id : "http://activitystrea.ms/specs/json/schema/activity-schema.html#read",
		display : {
			"en-US":"read", 
			"en-GB":"read"
		}
	});

You can learn more about verbs by reading Megan Bowe's excellent blog post on the subject. Here we are using the verb 'read' from the Activity Streams Base Schema.

Object

The 'Object' part of the statement (called 'target' in the Tin Can JavaScript library) is made up of an Activity Object with an Activity Definition nested inside like so:

	var myActivityDefinition = new TinCan.ActivityDefinition({
		name : {
			"en-US":item.volumeInfo.title, 
			"en-GB":item.volumeInfo.title
		},
		description : {
			"en-US":item.volumeInfo.description, 
			"en-GB":item.volumeInfo.description
		}
	});
 
	var myActivity = new TinCan.Activity({
		id : item.selfLink,
		definition : myActivityDefinition
	});

The activity definition contains name and description properties. We set the name as the title of the book and the description as the Google Books description. Note that as with the verb display, both these properties can be localized (according to RFC3066). This example shows titles and description for both en-US and en-GB.

For the activity id we use the Google Books API 'selflink' property which links to the full Google Books API definition of the item. There are, however, other options such as ISBN etc. Google stores these in an array as the volume's industryIndentifiers property.

Statement

Finally we pull the whole statement together as a TinCan Statement object:

	var stmt = new TinCan.Statement({
		actor : myActor,
		verb : myVerb,
		target : myActivity
	},false);

The second parameter here is set to false. If set to true tells the Statement object to stores the full statement as a JSON string in its 'originalJSON' property. We could then access this later using

stmt.originalJSON

As we don't need this later, however, this parameter can be left as false.

TinCan.sendStatement

Finally, we call our TinCan object's sendStatement method to send the statement to the LRS we defined earlier. This method has two parameters, the statement and a callback function. This callback will be called once the statement has been sent.

myTinCan.sendStatement(stmt, function() {...some funky code...});

In this example, the callback function runs some code which tells the user their statement has been sent. Once the callback has been called that's the end of the Tin Can realized code, so the end of this guide!

End of guide

I hope you found this guide helpful. As you can see, sending the Tin Can statement is pretty simple! Feel free to get in touch or ask about any aspect of this tutorial at all on Twitter @mrdownes or by email to mrdownes@hotmail.com