sdi_appstate-api
This bundle provides base components that are used to create, update, delete and load app states from map.apps SDI. These components are used for example by the sdi_appstate-ui
bundle.
Usage
App states are saved in the map.apps SDI database on the server, so it is required to install and configure the map.apps SDI savestate backend web application on the application server. You can find detailed installation instructions in the map.apps SDI product documentation.
How it works internally
The MainEncoderDecoder
component of this bundle collects all components that implement the sdi_appstate-api.EncoderDecoder
interface and creates a collective app state containing the data returned by the encode
methods of each of these EncoderDecoders. For example, the sdi_appstate-map
bundle has a component MapViewEncoderDecoder
that provides the interface sdi_appstate-api.EncoderDecoder
. Its encode
method returns the specific data required to restore the state of the map.
To restore the state, the MainEncoderDecoder
passes the saved data to the decode
methods of the respective EncoderDecoders.
Implementing custom EncoderDecoders
Developers can provide custom EncoderDecoder
components to enable more features of an app to be saved and restored.
Saving and restoring the state of a map.apps SDI app is performed by components that implement the sdi_appstate-api.EncoderDecoder
interface. So to create a custom EncoderDecoder, add a new component to the manifest.json
file of your bundle that looks as such:
{
"name": "CustomEncoderDecoder",
"provides": "sdi_appstate-api.EncoderDecoder"
}
The class for this component must implement the EncoderDecoder interface. Here is an example:
import {JSONValue} from "sdi_appstate-api/api";
export default class CustomEncoderDecoder implements EncoderDecoder {
readonly name: string;
async encode(): Promise<JSONValue> {
// Return the data saved to the database. Must be compatible with JSON.stringify
return {
mySavedProperty: this.myFeature.myProperty
}
}
async decode(data: JSONValue): Promise<void> {
// Apply the saved data to our component again
this.myFeature.myProperty = data.mySavedProperty;
}
}
- The
name
property uniquely identifies the EncoderDecoder. It is also required to structure the data which is saved to the database. encode()
returns the data required to restore the state as a JavaScript object. This object must be convertible to JSON, so it must not contain values likeFunction
,Symbol
, etc. (see JSON.stringify).decode(data)
restores the state with the data returned earlier by theencode
method.
Overriding app state properties with URL parameters
When using map.apps SDI together with the map.apps parameter-url
bundle, you can override certain properties if the name of the URL parameter is the same as a property in the app state.
Example
In this example, the c
parameter in the URL will override the c
property from the app state.
URL: sdi_appstate/index.html?c=7.13,52.4&bm=topo
App State:
{
"mapView": {
"c": "5.34,48.9"
}
}
Backward compatibility
map.apps SDI 5.5 is backward compatible with app states created with map.apps SDI versions prior to 5.5. However, if you implemented custom ParameterResolvers, you'll have to convert these to the new EncoderDecoder
interface. Additionally, add a mapping entry to the customDecoderMap
property of the LegacyStateConversionConfig
component. See the reference for details.
Configuration reference
The following sections describe the configurable components and properties for the app.json
of this bundle's components.
LegacyStateConversionConfig
In older versions of map.apps SDI, app states were structured according to the following schema:
{
"theme": "everlasting",
"vm": "2D",
"s": 9244648.868618,
"r": 0,
"c": "1137586.745771235,6501498.924616195",
"myProperty": "a"
}
All properties were stored at the root level of the app state object.
In the new format, the properties are grouped by the names of the corresponding EncoderDecoders:
{
"theme": {
"theme": "everlasting"
},
"mapView": {
"vm": "2D",
"s": 9244648.868618,
"r": 0,
"c": "1137586.745771235,6501498.924616195"
},
"myFeature": {
"myProperty": "a"
},
"_version": "5.5"
}
There is a new property _version
as well to easily distinguish the new format from the old one.
When loading a legacy app state the MainEncoderDecoder
needs to know the correct EncoderDecoder for each property. While in the new format it's easy to determine the corresponding EncoderDecoder for a certain property, we cannot figure this out in the old format. We need a map to get the correct EncoderDecoder name for a given property.
We can specify this map in the app.json
file with the customDecoderMap
property. In the following example, we add one entry to the map. It means "decode the property myProperty
with the EncoderDecoder with the name myFeature
".
{
"sdi_appstate-api": {
"LegacyStateConversionConfig": {
"customDecoderMap": {
"myProperty": "myFeature"
}
}
}
}
You only have to include the properties for custom EncoderDecoders. The default EncoderDecoders coming with map.apps SDI are already included in the defaultDecoderMap
.