C8oSDK Javascript
TOC
Introduction
About SDKs
This is the Convertigo library for Javascript
Convertigo Client SDK is a set of libraries used by mobile or Windows desktop applications to access Convertigo Server services. An application using the SDK can easily access Convertigo services such as Sequences and Transactions.
The Client SDK will abstract the programmer from handling the communication protocols, local cache, FullSync off line data management, UI thread management and remote logging. So the developer can focus on building the application.
Client SDK is available for:
This current package is the Javascript SDK. For others SDKs see official Convertigo Documentation.
About Convertigo Platform
Convertigo Mobility Platform supports Javascript developers. Services brought by the platform are available for Javascript clients applications thanks to the Convertigo MBaaS SDK. SDK provides an Javascript framework you can use to access Convertigo Server’s services such as:
- Connectors to back-end data (SQL, NoSQL, REST/SOAP, SAP, - WEB HTML, AS/400, Mainframes)
- Server Side Business Logic (Protocol transform, Business logic augmentation, ...)
- Automatic offline replicated databases with FullSync technology
- Security and access control (Identity managers, LDAP , SAML, oAuth)
- Server side Cache
- Push notifications (APND, GCM)
- Auditing Analytics and logs (SQL, and Google Analytics)
Convertigo Technology Overview
Access Convertigo mBaaS technical documentation
Access Convertigo SDK Documentations
Requirements
Installation
$ npm install --save c8osdkjs@latest
Documentation
Creating a C8o instance
import { C8o } from "c8osdkjs"
const c8o = new C8o()
Advanced instance settings
General
The endpoint is the mandatory setting to get a C8o instance correctly initialized but there is additional settings through the C8oSettings class.
A C8oSettings instance should be passed after the endpoint. Settings are copied inside the C8o instance and a C8oSettings instance can be modified and reused.
Setters of C8oSettings always return its own instance and can be chained.
A C8oSettings can be instantiated from an existing C8oSettings or C8o instance.
In order to finish the c8o initialization you must use init method from c8o object with a c8oSettings parameters
import { C8o, C8oSettings } from "c8osdkjs"
let settings: C8oSettings = new C8oSettings();
settings
.setEndPoint("https://demo.convertigo.net/cems/projects/sampleMobileCtfGallery")
.setDefaultDatabaseName("mydb_fullsync")
.setTimeout(30000);
c8o.init(settings);
c8o.finalizeInit().then(() => {
})
let timeout : number = c8o.timeout;
Normalize parameters
If you want to normalize parameters of every call you can set it throw C8osettings setNormalizeParameters method.
setNormalizeParameters
import { C8o, C8oSettings } from "c8osdkangular";
let settings: C8oSettings = new C8oSettings();
settings
.setNormalizeParameters(true);
c8o.init(settings);
let normalizeParameters : boolean = c8o.normalizeParameters;
Calling a Convertigo requestable
With a C8o instance you can call Convertigo Sequence and Transaction or make query to your local FullSync database.
The call method expects the requester string of the following syntax:
For a transaction: [project].connector.transaction For a sequence: [project].sequence The project name is optional, i.e. if not specified, the project specified in the endpoint will be used.
import { C8o, C8oSettings } from "c8osdkjs"
let result = await this.c8o.callJson('.login')
.async();
this.c8o.callJson(".login")
.async()
.then((response)=>{
});
this.c8o.callJson(".login")
.toObservable()
.subscribe(next => {
},
error =>{
},
() =>{
});
this.c8o.callJson(".login")
.then((response)=>{
});
Calling a Convertigo requestable with parameters
Convertigo requestables generally needs key/value parameters encapsuled in a simple javascript object.
The key is always a string and the value can be any object but a string is the standard case.
let result = await this.c8o.callJson('.login', {
login: "barnett.christine",
password: "mySuperPassword123"
})
.async();
this.c8o.callJson('.login', {
login: "barnett.christine",
password: "mySuperPassword123"
})
.async()
.then((response)=>{
});
this.c8o.callJson(".login",{
login: "barnett.christine",
password: "mySuperPassword123"
})
.then((response)=>{
});
Calling a Convertigo requestable uploading a files
Convertigo requestables supports file as argument. You can pass it as key value pair.
Indeed, the key is a string (name of the variable), and the value must be a Javascript File, or FileList. It can be into an array or directly passed as argument
let fileFirst = new File(["Hello Convertigo First !"], "fileFirst.txt", {
type: "text/plain",
});
let fileSecond = new File(["Hello Convertigo Second !"], "fileSecond.txt", {
type: "text/plain",
});
let result = await this.c8o.callJson('.sequenceThatReceiveAFile ', {
paramOne: "MyFirstParam",
files: [fileFirst, fileSecond]
})
.async();
this.c8o.callJson('.sequenceThatReceiveAFile', {
paramOne: "MyFirstParam",
files: [fileFirst, fileSecond]
})
.async()
.then((response)=>{
});
this.c8o.callJson(".sequenceThatReceiveAFile",{
paramOne: "MyFirstParam",
files: [fileFirst, fileSecond]
})
.then((response)=>{
});
Chaining calls
The .then() returns a C8oPromise that can be use to chain other promise methods, such as .then() or failure handlers. The last .then() must return a null value. .then() can be mixed but the returning type must be the same: Xml or Json.
c8o.callJson(".getSimpleData", "callNumber", 1)
.then((response) => {
return c8o.callJson(".getSimpleData", "callNumber", 2);
})
.then((response)=>{
parameters["callNumber"] = 3;
parameters["extraParameter"] = "ok";
return c8o.callJsonObject(".getSimpleData", parameters);
})
.then((response)=>{
return null;
})
Handling failures
A call can throw an error for many reasons: technical failure, network error and so on.
The standard try/catch should be used to handle this.
try{
let result = await this.c8o.callJson('.login', {
login: "barnett.christine",
password: "mySuperPassword123"
}).async();
}
catch(error){
}
this.c8o.callJson('.login', {
login: "barnett.christine",
password: "mySuperPassword123"
}).
.async()
.then((response)=>{
})
.catch((error)=>{
});
this.c8o.callJson(".login")
.toObservable()
.subscribe(next => {
},
error =>{
},
() =>{
});
this.c8o.callJson('.login', {
login: "barnett.christine",
password: "mySuperPassword123"
}).
.then((response)=>{
})
.fail((error)=>{
})
Writing the device logs to the Convertigo server
Basic
An application developer usually adds log information in his code. This is useful for the code execution tracking, statistics or debugging.
The Convertigo Client SDK offers an API to easily log on the standard device logger, generally in a dedicated console. To see this console, a device must be physically connected on a computer.
Fortunately, the same API also send log to the Convertigo server and they are merged with the server log. You can easily debug your device and server code on the same screen, on the same timeline. Logs from a device contain metadata, such as the device UUID and can help to filter logs on the server.
A log level must be specified:
- Fatal: used for critical error message
- Error: used for common error message
- Warn: used for not expected case
- Info: used for high level messages
- Debug: used for help the developer to understand the execution
- Trace: used for help the developer to trace the code
- To write a log string, use the C8oLogger instance of a C8o instance:
const error = anyError;
c8o.log.fatal("hello logs ! (level fatal)", error);
c8o.log.error("hello logs ! (level error)", error);
c8o.log.warn("hello logs ! (level warn)", error);
c8o.log.info("hello logs ! (level info)", error);
c8o.log.debug("hello logs ! (level debug)", error);
c8o.log.trace("hello logs ! (level trace)", error);
Advanced
A C8oLogger have 2 log levels, one for local logging and the other for the remote logging. With the Android SDK, the local logging is set by the logcat options. With the .Net SDK, the local logging depends of the LogLevelLocal setting of C8oSettings.
The remote logging level is enslaved by Convertigo server Log levels property: devices output logger. In case of failure, the remote logging is disabled and cannot be re-enabled for the current C8o instance. It can also be disabled using the LogRemote setting of C8oSettings, enabled with true (default) and disabled with false.
C8oSettings()
.setLogC8o(false)
.setLogRemote(false)
.setLogLevelLocal(C8oLogLevel.TRACE);
Using the Local Cache
Sometimes we would like to use local cache on C8o calls and responses, in order to:
- save network traffic between the device and the server,
- be able to display data when the device is not connected to the network.
The Local Cache feature allows to store locally on the device the responses to a C8o call, using the variables and their values as cache key.
To use the Local Cache, add to a call a pair parameter of "__localCache" and a C8oLocalCache instance. The constructor of C8oLocalCache needs some parameters:
- C8oLocalCache.Priority (SERVER / LOCAL): defines whether the response should be retrieved from local cache or from Convertigo server when the device can access the network. When the device has no network access, the local cache response is used.
- ttl: defines the time to live of the cached response, in milliseconds. If no value is passed, the time to live is infinite.
- enabled: allows to enable or disable the local cache on a Convertigo requestable, default value is true.
this.c8o.callJson(".getSimpleData",
{
"__localCache": new C8oLocalCache(Priority.LOCAL, 180 * 1000)
})
.then((response)=>{
});
this.c8o.callJson(".getSimpleData",
{
"firstname": "John",
"lastname": "Doe",
"__localCache": new C8oLocalCache(Priority.LOCAL, 180 * 1000)
})
.then((response)=>{
});
this.c8o.callJson(".getSimpleData",
{
"__localCache": new C8oLocalCache(Priority.SERVER, 3600 * 1000)
})
.then((response)=>{
});
Using the Full Sync
Full Sync enables mobile apps to handle fully disconnected scenarios, still having data handled and controlled by back end business logic. See the presentation of the Full Sync architecture for more details.
Convertigo Client SDK provides a high level access to local data following the standard Convertigo Sequence paradigm. They differ from standard sequences by a fs:// prefix. Calling these local Full Sync requestable will enable the app to read, write, query and delete data from the local database:
- fs://.create creates the local database if not already exist
- fs://.view queries a view from the local database
- fs://.get reads an object from the local database
- fs://.post writes/update an object to the local database
- fs://.delete deletes an object from the local database
- fs://.all gets all objects from the local database
- fs://.sync synchronizes with server database
- fs://.replicate_push pushes local modifications on the database server
- fs://.replicate_pull gets all database server modifications
- fs://.reset resets a database by removing all the data in it
- fs://.put_attachment Puts (add) an attachment to a document in the database
- fs://.bulk Bulk loads a database from a file
- fs://.info Get info for a given database
Where fs:// is the name of a specific FullSync Connector in the project specified in the endpoint. The fs:// name is optional only if the default database name is specified with the method setDefaultDatabaseName on the C8oSetting.
An application can have many databases. On mobile (Android, iOS and Xamarin based) they are stored in the secure storage of the application. On Windows desktop application, they are stored in the user AppData/Local folder, without application isolation.
All platforms can specify a local database prefix that allows many local database copies of the same remote database. Use the method setFullSyncLocalSuffix on the C8oSetting.
let resultReset = await this.c8o.callJson('fs://base.reset').async();
let resultPost = await this.c8o.callJsonObject('fs://base.post', {
firstname: "Jhonn",
lastname: "Doe"
}).async();
this.c8o.callJsonObject('fs://base.get', {
docid: resultPost['id']
}).async();
let resultGet = await this.c8o.callJson("fs://base.put_attachment",
"docid", id, "name", "text2.txt", "content_type", "text/plain", "content", new Blob(["Hello Convertigo !"], {type: "text/plain"})).async();
let resultGet = await this.c8o.callJson("fs://base.get", "docid", id, "attachments", true).async();
let resultInfo = await this.c8o.callJson("fs://base.info").async();
let resultBulk = await this.c8o.callJson("fs://base.bulk", "data", "http://myurl.com/dump.json").async();
Replicating Full Sync databases
FullSync has the ability to replicate mobile and Convertigo server databases over unreliable connections still preserving integrity. Data can be replicated in upload or download or both directions. The replication can also be continuous: a new document is instantaneously replicated to the other side.
The client SDK offers the progress event to monitor the replication progression thanks to a C8oProgress instance.
A device cannot pull private documents or push any document without authentication. A session must be established before and the Convertigo server must authenticate the session (using the Set authenticated user step for example).
this.c8o.callJson('.login')
.then((response)=>{
if(response == "ok"){
this.c8o.callJson('fs://base.replication_pull')
.then((response)=>{
})
.progress((progress)=>{
});
}
});
Replicating Full Sync databases with continuous flag
As mentioned above, a replication can also be continuous: a new document is instantaneously replicated to the other side.
Progress will be called at each entering replication during the all life of the application until that you explicitly cancel that one
this.c8o.callJsonObject('fs://base.replication_pull', {"continuous": true})
.then((response)=>{
})
.progress((progress)=>{
})
this.c8o.callJsonObject('fs://base.replication_pull', {"cancel": true})
.then((response)=>{
})
Full Sync FS_LIVE requests
Full Sync has the ability to re-execute your fs:// calls if the database is modified. The then or thenUI following a FS_LIVE parameter is re-executed after each database update. Database update can be local modification or remote modification replicated.
This allow you keep your UI synchronized with database documents.
A FS_LIVE parameter must have a string value, its liveid. The liveid allow to cancel a FS_LIVE request.
this.c8o.callJsonObject("fs://base.view",{
"ddoc": "design",
"view": "customers",
C8o["FS_LIVE"]: "customers"
})
.then((response)=>{
})
this.c8o.cancelLive("customers")
.then(()=>{
}
.catch((err)=>{
});
Full Sync Change Listener
Full Sync has also the ability to notify your if there is any change on the database. The progress following a FS_LIVE parameter is triggered after each database update. The changes contains the origin of the change, and other attributes :
- isExternal
- isCurrentRevision
- isConflict
- id
- revisionId
let changeListener : C8oFullSyncChangeListener = new C8oFullSyncChangeListener((changes:Object)=>{
checkChanges(changes);
});
…
c8o.addFullSyncChangeListener("databaseName", changeListener);
…
c8o.removeFullSyncChangeListener("databaseName", changeListener);
Full documentation is available on
Programming Guide