Skip to main content
Signature
QueryRuleCustomDataConnector(
    searcher: HitsSearcher,
    initialItem: T?,
    presenter: QueryRuleCustomDataPresenter<T>?,
)

About this widget

The QueryRuleCustomData widget displays custom data from Rules. You can use this widget to display banners or recommendations returned by rules when they match search parameters.

Examples

Instantiate a QueryRuleCustomDataConnector and launch an initial search on its Searcher, triggering a Rule that returns custom data.

Android view

Kotlin
class MyActivity : AppCompatActivity() {

    @Serializable
    data class Banner(val text: String) // Custom data model

    val searcher = HitsSearcher(
        applicationID = ApplicationID("YourApplicationID"),
        apiKey = APIKey("YourSearchOnlyAPIKey"),
        indexName = IndexName("YourIndexName")
    )
    val queryRuleCustomData = QueryRuleCustomDataConnector<Banner>(searcher)
    val connection = ConnectionHandler(queryRuleCustomData)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val bannerView = TextView(this)

        queryRuleCustomData.subscribe { banner ->
            banner?.text?.let { bannerView.text = it } // Display the banner
        }

        searcher.searchAsync()
    }

    override fun onDestroy() {
        super.onDestroy()
        connection.disconnect()
        searcher.cancel()
    }
}

Compose UI

InstantSearch provides the QueryRuleCustomDataState as a state model, which is an implementation of the QueryRuleCustomDataPresenter interface.
Kotlin
class MyActivity : AppCompatActivity() {
    val searcher = HitsSearcher(
        applicationID = ApplicationID("YourApplicationID"),
        apiKey = APIKey("YourSearchOnlyAPIKey"),
        indexName = IndexName("YourIndexName")
    )
    val queryRuleCustomDataState = QueryRuleCustomDataState<Banner>()
    val queryRuleCustomData = QueryRuleCustomDataConnector<Banner>(
        searcher = searcher,
        presenter = queryRuleCustomDataState
    )
    val connection = ConnectionHandler(queryRuleCustomData)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyQueryRuleCustomData(queryRuleCustomDataState) // your own UI composable to display your custom data
        }
        searcher.searchAsync()
    }

    override fun onDestroy() {
        super.onDestroy()
        connection.disconnect()
        searcher.cancel()
    }
}

@Serializable
data class Banner(val text: String) // your custom data model

Parameters

searcher
HitsSearcher
required
The Searcher that handles your searches.
initialItem
T?
Initial model value.
presenter
QueryRuleCustomDataPresenter<T>?
The Presenter defining how a model appears.
Kotlin
val queryRuleCustomData = QueryRuleCustomDataConnector<Banner>(searcher) { banner ->
    bannerView.text = banner.text
}

Low-level API

If you want to fully control the QueryRuleCustomData components and connect them manually, you can use the following components:
  • Searcher. The Searcher that handles your searches.
  • QueryRuleCustomDataViewModel. The component encapsulating the logic applied to the custom model.
  • QueryRuleCustomDataPresenter. Defines the way we want to interact with a model.
Kotlin
class MyActivity : AppCompatActivity() {

    @Serializable
    data class Banner(val text: String) // Custom data model

    val searcher = HitsSearcher(
        applicationID = ApplicationID("YourApplicationID"),
        apiKey = APIKey("YourSearchOnlyAPIKey"),
        indexName = IndexName("YourIndexName")
    )
    val queryRuleCustomDataViewModel = QueryRuleCustomDataViewModel(Banner.serializer())
    val queryRuleCustomData = QueryRuleCustomDataConnector(searcher, queryRuleCustomDataViewModel)
    val connection = ConnectionHandler(queryRuleCustomData)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        val bannerView = TextView(this)

        queryRuleCustomData.subscribe { banner ->
            banner?.text?.let { bannerView.text = it } // Display the banner
        }

        searcher.searchAsync()
    }

    override fun onDestroy() {
        super.onDestroy()
        connection.disconnect()
        searcher.cancel()
    }
}

Serialization

You must provide a DeserializationStrategy<T> implementation to deserialize your custom models. An easy way to achieve this is to annotate your custom model class with @Serialization. The Kotlin serialization compiler plugin then automatically generates an implementation for you, accessible using the .serializer() function on the class’s companion object.

Example

Suppose your custom JSON data contains a banner URL that can be decoded to the following structure:
Kotlin
@Serializable
data class Banner(val bannerUrl: String)
You can then either explicitly pass your serializer to the widget:
Kotlin
val queryRuleCustomData = QueryRuleCustomData(searcher, Banner.serializer())
Or, pass your custom model class as a generic argument:
Kotlin
val queryRuleCustomData = QueryRuleCustomData<Banner>(searcher)
I