Serializable Properties

Geocortex Web uses static, plain, app config JSON files to represent settings and properties for various components and services in an application. At some point, each of the values in the JSON file must be serialized and populate a JavaScript object. Component models and custom services can both consume configuration; therefore, they must also define the logic for translating configuration to runtime values.

Defining a Serializable Class#

In order for a component to participate in configuration, it must be marked as serializable with the @serializable decorator.

...
@serializable
export default class ExampleComponentModel extends ComponentModelBase<
ExampleComponentModelProperties
> {
items: Collection<string> = new Collection<string>();
...
}

Every serializable class extends a generically typed base class, like ComponentModelBase or ConfigurableServiceBase. The type passed into the base class is an interface consisting of primitive, serializable types, like number, string, array, boolean, etc. Each property on the interface will correspond exactly to a property in the app config JSON.

tip

Marking properties in the ComponentModelProperties interface as optional allows them to be left out of config and populated with default values. It's best practice to make properties optional and provide a default value if possible.

...
interface ExampleComponentModelProperties extends ComponentModelProperties {
items?: string[];
}
@serializable
export default class ExampleComponentModel extends ComponentModelBase<
ExampleComponentModelProperties
> {
items: Collection<string> = new Collection<string>();
...
}

Populating the Class with Configuration Values.#

The class is responsible for turning the ComponentModelProperties interface, which will be populated with primitive values from the app config JSON, into complex properties on the class object itself. This work is done through the _getSerializableProperties method.

The _getSerializableProperties() method has a few purposes.

  1. Provide deserialization logic from the ComponentModelProperties interface to class properties.
  2. Provide serialization logic from an class property to the ComponentModelProperties interface, which can be serialized in a JSON file.
  3. Provide a default value for the JSON object if one is not given in the app config.
important

It's key that the existing properties also get serialized through a call to super._getSerializableProperties().

In the following example, the serialization logic for the ExampleComponentModelProperties string array property items is defined. The corresponding class property is an ArcGIS API for JavaScript Collection. Therefore, the deserialize method takes each item from the string array, and adds it to to collection. The serialize method does the opposite, turning the collection into a plain string array. A default value for the string[] is also provided.

...
interface ExampleComponentModelProperties extends ComponentModelProperties {
items?: string[];
}
@serializable
export default class ExampleComponentModel extends ComponentModelBase<
ExampleComponentModelProperties
> {
items: Collection<string> = new Collection<string>();
...
protected _getSerializableProperties(): PropertyDefs<
ExampleComponentModelProperties
> {
const props = super._getSerializableProperties();
return {
...props,
items: {
serializeModes: ["initial"],
default: ["Some Default Value"],
serialize: () => this.items.toArray(),
deserialize: (items: string[]) => {
this.items.removeAll();
this.items.addMany(items); s
},
},
};
}
}

Already serializable properties such as boolean values or string values can have their serialization logic omitted.

...
interface ExampleComponentModelProperties extends ComponentModelProperties {
stringVal?: string;
}
@serializable
export default class ExampleComponentModel extends ComponentModelBase<
ExampleComponentModelProperties
> {
stringVal: string;
protected _getSerializableProperties(): PropertyDefs<
ExampleComponentModelProperties
> {
const props = super._getSerializableProperties();
return {
...props,
stringVal: {
serializeModes: ["initial"],
default: "Simple String Value",
},
};
}
}

Serialization Modes#

Every property has a number of serialization modes it can use to persist the values.

export declare type SerializeMode = "initial" | "all" | "preferences";

initial will serialize to the app config JSON only if it is different from the default.

all will serialize all values to the app config JSON every time.

preferences will serialize the value to storage which will persist between application loads, but only apply to a single user.

Next Steps#

Check out the Component Reference for Configuration

Learn more about how components interact with configuration

Check out the Service Reference for Configuration

Learn more about how services interact with configuration