Blueprint projects
- Frontend
- Blueprint assignments
- Blueprint builders
- Blueprint general
- Blueprint how to
- Blueprint tools
- Backend
Offline
Introduction
@capturum/complete supports offline functionalities. It uses indexedDb in combination with Dexie.js to accomplish this. This page will explain how to work with the indexedDb via the @capturum/complete package.
IndexedDbModel
To communicate with the IndexedDb @capturum/complete uses the Dexie.js package. An abstract IndexedDbModel class is used to communicate with the indexedDb. Here is an example of class which extends the IndexedDbModel class:
import { IndexedDbModel } from '@capturum/complete';
export class ProjectIndexedDbModel extends IndexedDbModel {
// Configuration
public entity = 'permission';
public table = 'permissions';
public schema = '++id, name';
// Fields
public name: string;
public projectType: string;
// Constructor
constructor(attributes) {
super(attributes);
}
}
In a class which extends the IndexedDbModel you have to define a few properties:
-
entity:
The name of the entity
-
table:
The name of the table in the indexedDb
-
schema:
The schema to be used by Dexie. Here you define all the properties which should be indexed by the indexedDb. You need to add any properties here on which you want to query.
In order for @capturum/complete to create a table in the indexedDb you have to add the class to the indexedDbModels property at the forRoot config of the CoreModule and up te version in the forRoot config.
Querying
To query the indexedDb through the IndexedDbModel you have to use the static query() method. For example ProjectIndexedDbModel.query() This will return a Dexie table instance. Now you can use any Table method which is provided by dexie:
ProjectIndexedDbModel.query().where({name: 'emendis'}).first();
Sync
@capturum/complete provides a way to synchronize/post the data in the indexedDb to the backend. A SyncService has been created to support this functionality. This service provides methods to retrieve the data which has to be synchronized and post this to the backend. The way this works is as followed:
Entities
-
- First it looks for the data which is either changed or deleted. It will only look in the tables which are specified in the forRoot configuration
syncConfig.models. See the configurations page to find out more. This data is recognized by theis_changedand the_deletedproperty. If either of those properties equals 1 then it will be synced to the backend. - Once it has collected the data to be synced it will execute the POST call to the backend.
- Once a 200 status response is returned it will process the returned data and clean up the indexedDb if specified. The data is of the following interface:
export interface SyncResponse { [key: string]: { deleted: string[]; mutated: any[]; errors: { type: 'validation' | 'exception'; data: any; }[]; }; }If the parameter
deleteResourcesAfterSynchas been set to true then it will remove all the successfully synced entities from the indexedDb. This means it will only delete the entities which are not present in the errors response. - First it looks for the data which is either changed or deleted. It will only look in the tables which are specified in the forRoot configuration
Files
Files are synced separately because the request body would become too large if it was sent in the same POST call as the entity data. The synchronization of files works very similar to the entity synchronization. Except this time it will only look in the files table of the indexedDb. It still looks for either _changed or _deleted to be 1. After that it will POST the files one by one to prevent too large request bodies. After it has done all the requests it will once again clean up the indexedDB based on the response of the backend.
Usage example
import { SyncService } from '@capturum/complete';
class AppComponent {
constructor(private syncService: SyncService) {}
public syncTheData(): void {
// Sync the entities
this.syncService.sync().subscribe(() => {
// Do someting cool after the sync
});
// Sync the entities without them being removed after successfull sync
this.syncService.sync(false).subscribe(() => {
// Do someting cool after the sync
});
// Sync the files
this.syncService.syncFiles().subscribe(() => {
// Do someting cool after the sync
});
}
}