1 min read

Custom Data

Custom data is a mechanism that allows your app to send or receive extra information in the existing PoqSDK models to accommodate your customisations. Custom data is defined in domain and UI models as Any? and as Map<String, Any>? in network models.

Custom data in network models only allows JSON objects and not primitives.

Receive custom data

To add custom data to domain models you need to:

  1. Define a new domain model CustomModel which represents your extra fields.
  2. Provide a new implementation of Mapper<Any, Map<String, Any>>
    class CustomModelMapper: Mapper<Any, Map<String, Any>> {
    override fun map(origin: Map<String, Any>): Any {
    return CustomModel(origin["fieldName"] as {FieldType})
    }
    }
  3. Provide your new mapper via Koin using the appropriate name. Names are constructed as {ModelName}CustomMapToAnyMapperName but you should check the exact name in the features section or its Koin module.
  4. Where you want to use that extra information: (poqModel.customData as CustomModel).newField

In some features there is also a UI model, in these cases the Android PoqSDK will map your custom data automatically to the UI model.

If you need to use your custom data fields in your custom layouts via DataBinding, PoqSDK ViewModels expose the custom data or the whole object containing the custom data as LiveData, so you can:

  1. Create an extension function over the ViewModel interface
    fun PoqViewModel.customField(): LiveData<{YourFieldType}> {
    return Transformations.map(customData){ it.newField }
    }
  2. Use your new LiveData in your layout:
    <data>
    <variable
    name="viewModel"
    type="{package}.PoqViewModel" />
    <import type="{package}.FileExtensionsKt" />
    </data>
    <View
    android:field="@{FileExtensionsKt.customField(viewModel)}" />

Send custom data

When you need to send custom data to your backend, you need to:

  1. Define a new domain model CustomModel which represents your extra fields.
  2. Add your custom data object to the Domain model object. This is different for each domain and specific scenario.
  3. Provide a new implementation of Mapper<Map<String, Any>, Any>
    class CustomModelMapper: Mapper<Map<String, Any>, Any> {
    override fun map(origin: Any): Map<String, Any> {
    return HashMap<String, Any>().apply {
    this["fieldName"] = (origin as CustomModel).field
    }
    }
    }
  4. Provide your new mapper via Koin using the appropriate name. Names are constructed as {ModelName}CustomanyToMapMapperName but you should check the exact name in the features section or its Koin module.