Getting Started
Designed to work with the WebSocket, this SDK provides you with simple object definitions that work with our WebSocket server.
Embed API
To use the JavaScript API, all you need to do is include the script a single file reference in your HTML page. You will need to include this file before all your other JavaScript files includes. You can add this file to the <head>, but we recommend all files be included just before the closing </body> tag.
<script type="text/javascript" src="https://apis.fleetfreedom.com/js/trakit.fleetfreedom.js"></script>
Once the file is embedded in your page, an object is created in the global context; trakit.fleetfreedom. Every object discussed in this guide from here on will not include reference to this namespace. That means if we talk about the Asset class, we really mean the trakit.fleetfreedom.Asset class.
If you are planning to build your JavaScript project using the Fleet Freedom API, please use two external references; the first is the API file and the second is our JSDoc helper.
@extern https://apis.fleetfreedom.com/js/trakit.fleetfreedom.js
@extern https://apis.fleetfreedom.com/js/jsdoc.js
Object inheritance and event handling
Our API implements a custom event model similar to the DOM, but with a few limitations. First, all DOM event handlers will execute for a given event, but since our event raising system relies on looping through an array, if one of the event handlers throws a JavaScript exception, the rest of the handlers for that event will not be executed. To avoid this, test your code reletlessly, and when in doubt wrap any handlers with a try ... catch block.
Most of the classes (and objects) defined in our API inherit from the abstract class MVCObject; this class provides methods for binding and unbinding event handlers, and for firing events. To create a class which inherits from MVCObject:
function MyClass(arg1, arg2) {
// implement your class' constructor
// call MVCObject constructor last
MVCObject.call(this);
}
// inherit MVCObject
utility.inherits(MVCObject, MyClass);
// then define your class' prototype functions
MyClass.prototype.myFunc = function () {
// my custom functionality
};
You can also use utility.inherits function for any other inheritance chains needed in your code. Note: you will still have to call the parent class' constructor in your child class' constructor.
Event handlers are called in the context of the object instance (the this keyword references the object raising the event) with an MVCEvent object, and an optional second argument object you define.
function handlerOne(event) {
console.log(event.type);
}
var myObj = new MyClass("one", "two");
myObj.on("event-one", handlerOne);
myObj.once("event-one", function(event) { console.log(event.type + " and done"); });
myObj.fire("event-one") // => console logs "event-one", and "event-one and done"
myObj.fire("event-one") // => console logs "event-one"
myObj.off("event-one", handlerOne); // unbinds a specific handler
myObj.fire("event-one") // => nothing happens
myObj.on("event-two", function(event, details) { console.log(event.type + " " + details); });
myObj.fire("event-two", "with details") // => console logs "event-two with details"
myObj.off("event-two"); // unbinds all handlers for this event
myObj.fire("event-two", "again");// => nothing happens
There is also a function uses which returns a true if the function is currently bound to that object's event. The on method uses this function internally to ensure a function is not bound to an event twice.
Using the WebSocket
The socket object makes interfacing with the WebSocket simple. Sending commands is more useful since the socket keeps track of each request, a callback can be specified for any command sent to the WebSocket. The socket object provides an easy way of connecting and re-connecting, sending commands and setting up subscriptions. Each message received from the WebSocket is fired as an event with the message name as the event type, and the JSON message as the detail.
Below is a simple example of how to open the WebSocket, get your company details, subscribe to asset updates, and get a list of assets.
var company = new Company({
"id": 42,
"name": "my company"
});
// open the socket and login is needed
socket.on("open", function(event, json) {
if (!json.user) { // not a reconnect, so login
socket.send("login", {
"username": "email address",
"password": "",
"userAgent": "client software name"
}, afterLogin);
} else {
afterLogin();
}
});
socket.open();
function afterLogin() {
// get updated company details
socket.send("getCompany", { "company": {
"id": 42,
}
}, function(response) {
company.fromJSON(response.company);
});
// listen for asset updates
socket.on("assetGeneralMerged", assetMerged);
socket.on("assetAdvancedMerged", assetMerged);
socket.on("assetDeleted", assetDeleted);
socket.send("subscribe", {
"company": {
"id": 42,
},
"subscriptionTypes": [
"assetGeneral",
"assetAdvanced"
]
});
// get a list of all assets
socket.send("getAssetsList", {
"company": {
"id": 42,
}
}, afterAssets);
}
// populate the company with all the current assets
function afterAssets(response) {
response.assets.forEach(function(json) {
assetMerged(null, json);
});
}
// for each asset update, synchronize the asset object
function assetMerged(event, json) {
var asset = company.getAssetById(json.id);
if (asset) {
asset.fromJSON(json);
} else {
company.createAsset(json);
}
}
// remove any deleted assets from the company
function assetDeleted(event, json) {
var asset = company.getAssetById(json.id),
index = company.assets.indexOf(asset);
if (index > -1) {
company.assets.splice(index, 1);
}
}
Note: The subscription comes first just in case assets are updated while the asset list is being gathered and trasmitted.
The socket also adds a non-HttpOnly cookie to the browser ghostId which allows the socket to reconnect automatically to your previous session. This means you don't need to send a login with each connection.