Appery.io

The Appery.io Developer Hub

Welcome to the Apperyio developer hub. You'll find comprehensive guides and documentation to help you start working with apperyio as quickly as possible, as well as support if you get stuck. Let's jump right in!

Guides    Latest Updates

Offline

Working with the offline mode.

Introduction

API Express supports offline mode that is made with help of App Client . Here is how it works:

  • Initially, your app will be in online mode (state = online) no matter whether the internet on the device was enabled or not.
  • When the client goes offline (state = offline), all change-requests (POST, PUT, DELETE) to the server are going to be queued and stored to the Cache.
  • When the client goes online (state = synchronizing), the queue of deferred change-requests will be handled, and one after one, all the requests will be executed.
  • In case of a synchronization conflict (state = sync-failed), the error will be stored.
    When a device is connected to the internet, CliendSDK synchronises to the server and sends all offline changes made by the user. The mobile app automatically detects a connection state and switches the CliendSDK to an online/offline mode when the connection state has changes. In AppClientSettings service there is an option called handleNetworkState that is activated by default. You can disable this if need be.

There are few functions in ClientSDK library that help to handle switching between online and offline modes, and also trigger the synchronization or reset data that failed to sync. Initially, ClientSDK is not included in your Appery.io app. It will be added to the app as AppClientInit.js (it will be listed under JavaScript folder), during services generation via API Express Generator extension.

This diagram will give you an overview of the online-offline functionality works.

Online-offline diagram.

Online-offline diagram.

There are two types of generated REST API services:

  1. Services that return data (operations find and read).
  2. Services that modify data (operations create, update, delete).

Every API Express model has predefined structure (predefined fields and their types). When an app is online and performs find or get operation, the Client SDK saves the returned data in app storage (IndexedDB).

When an app is in offline mode, the Client SDK returns data of a get and find operations from storage (cache).

Operations create, update and delete modify data in storage and the sequence of operations performed is placed into history.

Operation create, update and delete modify data in storage (cache).

After switching from offline to online mode synchronization process will start running.

This means that the app needs to synchronize data with the server after a disconnect. In order to do that:

  • App replicates changes (which were made in the app when the app was offline) with server.
  • Server replicates changes (which were made on server when the app was offline) with app.

Replication means intelligently copying data from one location to another.

Network State Detection

The AppClient from the Client SDK can detect internet connection state change automatically.

The handleNetworkState option can be used to enable/disable automatic internet state detection during initialization. Automatic internet state detection is activated by default.

When handleNetworkState is enabled (value is true) then the AppClient checks internet connection state during initialization and goes to the appropriate mode.

After initialization finished the AppClient starts watching for internet connection state changes all the time.

If handleNetworkState is disabled (value is false) then the app logic should watch for internet state change and switch AppClient to the appropriate state manually.

Using on AppClient test page

The Handle network state option is available on the AppClient test page . added on SDK Settings panel. Use this option before AppClient initialization.

Using in an App

If API Express services are used in an app then Services folder will have the AppClientSettings file. This is the place where settings for AppClient are stored.

If an app should be notified about AppClient state change, then an app can subscribe to AppClient statechange event.

Using in a jQuery Mobile app

The following code will detect state change in a jQuery Mobile app:

//first get initialized AppClient instance
mssdk().then(function(AppClientInstance){
    //subscribe to AppClient state updates
    AppClientInstance.on("statechange", function(currentState){
        //doing something depends on new AppClient state
    });
});

Using in an Ionic/Bootstrap app

The following code will detect state change in an Ionic/Bootstrap and AngularJS app:

//first get initialized AppClient instance
Apperyio.get("mssdk")().then(function(AppClientInstance){
    //subscribe to AppClient state updates
    AppClientInstance.on("statechange", function(currentState){
        //doing something depends on new AppClient state
    });
});

Clearing Model Cache

Get DAO (Data Access Object) object for specific model from AppClient. Cache can be cleared using the clearCache function of the DAO object.

jQuery Mobile App

Clearing cache in a jQuery Mobile app:

var exampleModelDAOObject = AppClient.dao("exampleModel");
exampleModelDAOObject.clearCache().then(function(){
    //success
}, function(error){
    //error
});

Ionic/Bootstrap App

Clearing cache in an Ionic/Bootstrap and AngularJS app:

var exampleModelDAOObject = Apperyio.get("AppClientService").dao("exampleModel");
exampleModelDAOObject.clearCache().then(function(){
    //success
}, function(error){
    //error
});

User Auto Login

When auto login feature is enabled (autoLogin option in AppClientSettings) then during AppClient initialization, if user was logged in before, a login will be automatically executed. For example, an app has a login page and when it starts, app needs to know if a user is logged in or not. In this case isUserLoggedIn function of AppClient can be used.

jQuery Mobile App

Auto user login in a jQuery Mobile app:

mssdk().then(function(AppClientInstance){
    AppClientInstance.isUserLoggedIn().then(function(result){
        if(!result){
            //stay on login screen
        }else{
            //user is logged, skip login
        }
    });
});    

Ionic/Bootstrap App

Auto user login in an Ionic/Bootstrap and AngularJS app:

Apperyio.get("AppClientService").isUserLoggedIn().then(function(result){
    if(!result){
        //stay on login screen
    }else{
        //user is logged, skip login
    }
});

goOffline

ClientSDK can change the mode to offline from an online state only. During any offline work all of the calls to the server will be deferred (persisted in localStorage/indexedDB in a queue).

For AngularJS projects, the following works:

Apperyio.get("AppClientGeneralOperations").goOffline();

For jQM projects:

mssdk().then(function(sdk) {sdk.goOffline();});

goOnline

ClientSDK can switch the app mode to online only from offline state. During the process of going online, deferred server calls stored in the cache are to be performed during this synchronisation process – state = synchronising.
Every cached operation will be executed one-by-one. The Synchronisation process will stop in case of an error (state = sync-failed).
For AngularJS projects:

Apperyio.get("AppClientGeneralOperations").goOnline();

For jQM projects:

mssdk().then(function(sdk) {sdk.goOnline();});

retrySync

retrySync function can be executed to retry the synchronisation process and will work only when state = sync-failed.

For AngularJS projects:

Apperyio.get("AppClientGeneralOperations").retrySync();

For jQM projects:

mssdk().then(function(sdk) {sdk.retrySync();});

resetFailedSync

resetFailedSync will erase all of the operations that were not performed successfully. The operations that were executed successfully will not be affected; it will only work when state = sync-failed.
After this operation execution, switching the app mode to online will be performed.
For AngularJS projects:

Apperyio.get("AppClientGeneralOperations").resetFailedSync();

For jQM projects:

mssdk().then(function(sdk) {sdk.resetFailedSync();});

getState

Use getState method to determine the current app state.
For AngularJS projects:

Apperyio.get("AppClientGeneralOperations").getState().then(function(state) {});

Here is how the state can be shown in the console:

Apperyio.get("AppClientGeneralOperations").getState().then(function(state) {console.log(state);});

jQM projects:

mssdk().then(function(sdk) {console.log(sdk.state);});

revertLocalChanges

Use the revertLocalChanges method to revert all local changes made in offline mode without clearing the cached data. It can also be useful in case of a failed synchronisation or conflicted objects.
For AngularJS projects:

Apperyio.get("AppClientGeneralOperations").revertLocalChanges().then(function(){
 //Reverted
}, function(error){
 //Error
});

jQM projects:

invokeAppClientMethod("revertLocalChanges").then(function(){
 //Reverted
},function(){
 //Error
});

getDeferredActions

By using the getDeferredAction you will return the iterator, which you can use further to iterate through the array items. History in this case is the type of array. This array contains deferred actions that will be executed only if app goes online, so that is why they are deferred.

For AngularJS projects:

Apperyio.get("AppClientGeneralOperations").invokeAppClientMethod("getDeferredActions").then(function(historyIterator){
   var historyIteratorResult = historyIterator.next();
   while(!historyIteratorResult.done){
      var historyItem = historyIteratorResult.value;
      //work with historyItem
      historyIteratorResult = historyIterator.next();
   } 
}, function(error){
 //Error
});

jQM projects:

AppClient.getDeferredActions().then(function(historyIterator){
   var historyIteratorResult = historyIterator.next();
   while(!historyIteratorResult.done){
      var historyItem = historyIteratorResult.value;
      //work with historyItem
      historyIteratorResult = historyIterator.next();
   }
}, function(error){
 
});

A retrieved object (called historyIterator in current example) has the following methods:

  • next() – returns JSON object of the stored action with following structure:
{
   done: false,
   value: historyItem //history item object
}
  • done – end of history items indicator, if true then there are no more history items.
  • value – actual history item value has the following structure:
{
   modelName: name, //model name
   operation: operation, //operation on model
   content:{
      data: operationData, //operation data
      revertedData: revertedData, //data before operation
   },
   httpErrorResponse: error // exists if synchronization process failed on current history item
}
  • remove() – removes current action from the history.

saveDeferredActions

If you modified the history of saved deferred actions, you should save the changes by using the saveDeferredActions method.
For AngularJS projects:

Apperyio.get("AppClientGeneralOperations").invokeAppClientMethod("saveDeferredActions").then(function(){
 //history saved
}, function(error){
 //error
});

jQM projects:

AppClient.saveDeferredActions().then(function(){
 //history saved
}, function(error){
 //error
});