. . .

JavaScript SDK

This documentation will guide you to the usage of the JavaScript SDK. Please read the JavaScript Quickstart Guide to see how ApiOmat works. For a quick overview our Cheat Sheet is helpful.

The JavaScript SDK is generated for your app individually and the whole content of the SDK is located in its own namespace “Apiomat”.

But the operations you do within these objects and classes (create, read, update, delete, referencing, etc.) remain the same.

For this guide we’ll create an app with the following classes and attributes:

App name: YourConference

  • Class: Conference

    • name (Text)

    • ranking (Floating point)

    • image (Image)

    • confSessions (Collection of ConfSession)

    • tags (Collection of Strings)

  • Class: ConfSession

    • name (String)

    • fromTime (Date)

    • toTime (Date)

    • i18n_name (Map)

    • conference (Conference)

Working with Users

In the ApiOmat ecosystem we call users User. A User is a client that sends requests to our backend. So a User is a unique user of your website, app, etc. User normally logs into the backend.

To manage users, we have several functions implemented. First of all, you have to configure the Datastore to use the user login credentials.

var user = new Apiomat.User();
user.setUserName("user12");
user.setPassword("123asdf");
Apiomat.Datastore.configureWithCredentials(user);

Now your connection to our servers is initialized and you can start by logging or signing up. To sign up with a new user, call the following function on the user object.

user.save({
onOk: function() {
//Successfully sign up
},
onError: function(error) {
//do error handling
}
});

After this you are ready to send requests. If you already have an existing user, please call

user.loadMe({
onOk: function() {
//Successfully logged in.
},
onError: function(error) {
//do error handling
}
});

to log in the user with his credentials.

There is a common pattern you can use for handling the login or, on failure, creating a new sign-up.

var user = new Apiomat.User();
user.setUserName("_username_");
user.setPassword("_password_");
Apiomat.Datastore.configureWithCredentials(user);
var saveCB = {
onOk: function() {
//Successfully signed up. let's go
},
onError: function(error) {
//DO error handling on signup failure
}
};
user.loadMe({
onOk: function() {
//login was successfull. let's go
},
onError: function(error) {
//auth error occured so let's create a sign up
if(error.statusCode === Apiomat.Status.UNAUTHORIZED) {
user.save(saveCB);
} else {
//handle other errors
}
}
});

Handling Objects

Let’s have a look how we work with plain objects and do CRUD operations in them. Every object in our system has a HREF. This URL identifies an object. Note that all requests to ApiOmat are async. That means that we need a possibility to get notified when the request is finished. Our JavaScript SDK works with callback objects that are given these functions. The callback object has the follow generic format:

{
onOk: function([result]) {
//Request successful
//If server returns anything than you will find this in the result variable
},
onError: function(error) {
/*
Request failed
the parameter error contains more information
see also section about Error handling below
*/
}
}

Save an object

Saving an object in the backend is always following the same pattern:

var conference = new Apiomat.Conference();
//you may set some attributes here
conference.save({
onOk: function() {
//Successfully saved
},
onError: function(error) {
//do error handling
}
});

The command in line 2 saves the object of type “conference” in the ApiOmat backend.

Getting an object

To get a single object you have to know his unique identifier (the HREF). By using following command you are able to get a specific object.

var href = "https://apiomat.org/yambas/rest/apps/Conference/models/ConferenceMain/Conference/0123456"
var conference = new Apiomat.Conference();
conference.loadWithHref(href, {
onOk: function() {
//Successfully saved
},
onError: function(error) {
//do error handling
}
});

If you need to reload the data from server use the following code:

loadedObj.load({
onOk: function() {
//Successfully saved
},
onError: function(error) {
//do error handling
}
});

Getting a list of objects

You can also retrieve a list of objects from server.

//Load list of conference objects
Apiomat.Conference.getConferences(undefined,{
onOk: function(objects) {
//Getting list was successful
//You can now work with parameter objects which contains loaded elements
},
onError: function(error) {
//do error handling
}
});

Instead of ‘undefined’ you can add a query. You can find information about queries in the respective section.

Update an object

It’s identical to saving. The client code checks, if the object already contains a HREF and afterwards performs an update. For example:

//Get or save updatedObj
//Change sth on updatedObj
 
udpatedObj.save({
onOk: function() {
//Successfully updated
},
onError: function(error) {
//do error handling
}
});

Delete an object

According to our pattern, you can delete an object simply by using the following:

obj.deleteModel({
onOk: function() {
//Successfully deleted
},
onError: function(error) {
//do error handling
}
});

Offline Handling

The ApiOmat JavaScript SDK provides a mechanism to cache, save and update operations on objects while the device is offline. If network come back the cache will be flushed and changes are transferred to the backend in the right order. This works transparent for the user so you can work with offline objects in the same manner as with other objects. By default this behavior is deactivated. You can enable offline handling with the following statement:

Apiomat.Datastore.setOfflineStrategy(
Apiomat.AOMOfflineStrategy.USE_OFFLINE_CACHE, {
onOk : function()
{
//Cache is initalized
},
onError : function(err)
{
//Error occurred
}
});

This function call is a asynchronous call and you have to wait until callback object is called before go further in your code. The second parameter is the callback object. If cache/offline initialization was OK, than the onOk function is called, otherwise the onError.

For detailed information on Offline Handling and how to use it in ApiOmat, see this page: Offline Handling.

Working with properties of objects

Of course you can access properties, that you’ve created in your dashboard the standard javascript way. Please be careful to use the appropriate data type. It’s not recommend to add new properties to generated classes, because it will break serialization if you call the ‘save’ function to send an instance of the class to the server.

Setting a property

Assuming our conference class has a property called ‘name’, you can set this property easily with

var conference = new Apiomat.Conference();
conference.setName("JavaScript Dev Con");

or set a map (associative array, javascript object), which looks like this

var i18ns = {
"de" : "Wie benutze ich properties",
"en" : "Talk about properties"
}
confSession.setI18n_name(i18ns);
//save object on server
confSession.save();

Getting a property

Like accessing “normal” javascript properties, you can also access properties of ApiOmat classes.

//Make sure you loaded object conference before (see above)
var confName = conference.getName();

Working with geo points

You can also set ‘Location’ as type of a property. To save a property with name ‘place’ please call:

conference.setPlaceLatitude(10.2);
conference.setPlaceLongitude(20.2);

To retrieve coordinates, you can call the methods ‘getLatitude’ and ‘getLongitude’.

var latitude = conference.getPlaceLatitude();
var longitude = conference.getPlaceLongitude();

Working with images

It’s possible to add a property of type ‘image’ to your classes. If you do this, you can find some special functions in the generated code for this class. Upload an image to your class instance as an ArrayBuffer. Take a look at this page if you don’t know how you transform an image to that type. The function which adds an image is named after the pattern ‘post’. For our ‘Conference’ class and its property ‘image’ it should look like in following snippet.

var imgArr = [0,2,6,2];
conference.postImage(imageArr,{
onOk: function() {
//Successfully uploaded image
},
onError: function(error) {
//do error handling
}
});

If the image was uploaded, the property ‘URL’ contains an URL to the image. To get this image URL back from your object, you can call a function like ‘getURL’ with some parameters for re-sizing and image format.

//Get plain URL without concerting parameters
var imgUrl = conference.getImageURL();
//Get URL with resized image to 200x100
var resizedImgUrl = conference.getImageURL(200,100);

If you set only the width or height parameter, the image will be re-sized so that scale isn’t lost.

For a more detailed description of handling images you can read the specific documentation page.

Handling References

By adding attributes containing references, you are able to build data structures in an object oriented manner. You can reference a single or a list of classes.

You can add a list of type ConfSession to your Conference class or set a Conference as a reference of the ConfSession class, for example. The generated SDKs will contains several methods starting with ‘post..’, ‘load…’ or ‘remove…’ afterwards.

Add a reference

Our example Conference class contains a property ‘confSessions’ which is of type ‘Collection of ConfSession’. To add a ConfSession to an object of type Conference you can do the following:

//Create and save an object of type ConfSession (see above)
//Create and save an object of type Conference (see above)
 
conference.postConfSessions(confSession,{
onOk: function() {
//Successfully saved the reference on object conference
},
onError: function(error) {
//do error handling
}
})

Get references

To retrieve the referenced object(s) you have to call the ‘load’ function for this property. This function downloads the object(s) from the backend. After this you can access the local list by calling ‘get’.

//Assume that our object conference has already referenced confSessions
conference.loadConfSessions(undefined, {
onOk: function() {
//Successfully returned references
//Access local property
var confSessions = conference.getConfSessions();
},
onError: function(error) {
//do error handling
}
});

Instead of ‘undefined’ you can set a query parameter to filter the list. For this please see the following section about Query Handling.

Be aware that you can only set a query on collection of references. If there only one reference, then the function call is slightly different:

//Assume that our object conference has a property called singleRef which is a Reference to another class
conference.loadSingleRef({
onOk: function() {
//Successfully returned reference
//Access local property
var singleRef = conference.getSingleRef();
},
onError: function(error) {
//do error handling
}
});

Update a reference

If you change properties of an object which is already referenced to another object and sends the update to the server, than the reference will also be changed. If you call ‘load’ again you will retrieve the actualized references.

If you add an existing reference again to the same object it will not be added again as new reference.

Delete reference

Delete a reference between objects is straightforward.

//Assume that conference contains a reference to confSession
//Assume that both objects (conference, confSession) are loaded from server
conference.removeConfSessions(confSession);

Queries

Our backend supports a lot of query operations. For the full documentation please see here.

Let’s have a look at some examples.

Retrieving a filtered list

To get a list of objects you can set the query parameter.

//Load list of conference objects filtered by name
Apiomat.Conference.getConferences("name like \"Backend\"",{
onOk: function(objects) {
//Getting list was successful
//You can now work with parameter objects which contains loaded elements
},
onError: function(error) {
//do error handling
}
});

This will load a list of Conference objects, but only contains objects where the names include ‘backend’.

Retrieving filtered list of references

If you only want a subset of referenced objects, you can call the ‘load’ function like this.

//Assume that our object conference has already referenced confSessions
conference.loadConfSessions("name ==\"backend\"", {
onOk: function() {
//Successfully returned referenced confSessions with name 'backend'
//Access local property
var confSessions = conference.getConfSessions();
},
onError: function(error) {
//do error handling
}
});

The example above will load only referenced objects where the name is ‘backend’ or contains that word.

Error Handling

Every request you send will enter the callback object you have given the function to act as a parameter. If an error occurs while sending the request the ‘onError’ function of your callback object will be called with a parameter ‘error’. This ‘error’ is an object of type Apiomat.ApiomatRequestError. You can call the following function on this object:

  • message: Gives you a textual description of the error

  • statusCode: The returned status code

  • getStatusObj: Give you an object of type Apiomat.Status if the statusCode can be mapped to one

  • expectedCodes: Returns the HTTP status codes that this request expected

An example will demonstrate the access to an ‘error’ object:

conference.loadConfSessions(undefined, {
onOk: function() {
//Successful
},
onError: function(error) {
//Error handling
var errorCode = error.statusCode;
var description = error.message;
}
});

The class ‘Apiomat.Status’ contains references to every statusCode that can occur. Also, you can find a textual description of these codes there. You can compare the returned statusCode with a property of the type ‘Apiomat.Status’.

var callback = {
onOk: function() {
//Successful
},
onError: function(error) {
//Check if error was an auth error
if(error.statusCode == Apiomat.Status.UNAUTHORIZED) {
//Handling this error
}
}
}
* link only available in Enterprise Documentation