
ReactiveList creates a data-driven result list UI component. This list can reactively update itself based on changes in other components or changes in the database itself.
Example uses:
- showing a feed of results based on the applied search criteria.
Usage
Basic Usage
<template>
<reactive-list :react="{ and: ['CitySensor', 'SearchSensor']}">
<template #renderItem="{ item }">
<div>
{{ item.title }}
</div>
</template>
</reactive-list>
</template>Usage With All Props
<reactive-list
componentId="SearchResult"
compoundClause="filter"
dataField="ratings"
vectorDataField="vector_data" # Only one of dataField or vectorDataField is needed
paginationAt="bottom"
loader="Loading Results.."
prevLabel="Prev"
nextLabel="Next"
sortBy="desc"
:pagination="false"
:pages="5"
:size="10"
:candidates="10"
:showResultStats="true"
:react="{ and: ['CitySensor', 'SearchSensor'] }"
:endpoint="{
url:'https://appbase-demo-ansible-abxiydt-arc.searchbase.io/recipes-demo/_reactivesearch.v3',
headers: {
// put relevant headers
},
method: 'POST'
}"
/>Props
componentId
| Type | Optional |
|---|---|
String |
No |
unique identifier of the component, can be referenced in other components' react prop.
compoundClause
| Type | Optional |
|---|---|
String |
Yes |
Configure whether the DSL query is generated with the compound clause of must or filter. If nothing is passed the default is to use must. Setting the compound clause to filter allows search engine to cache and allows for higher throughput in cases where scoring isn’t relevant (e.g. term, geo or range type of queries that act as filters on the data)
This property only has an effect when the search engine is either elasticsearch or opensearch.
Note:
compoundClauseis supported with v8.16.0 (server) as well as with serverless search.
endpoint
| Type | Optional |
|---|---|
Object |
Yes |
endpoint prop provides the ability to query a user-defined backend service for this component, overriding the data endpoint configured in the ReactiveBase component. Accepts the following properties:
- url
String[Required] URL where the data cluster is hosted. - headers
Object[optional]
set custom headers to be sent with each server request as key/value pairs. - method
String[optional]
set method of the API request. - body
Object[optional]
request body of the API request. When body isn't set and method is POST, the request body is set based on the component's configured props.
- Overrides the endpoint property defined in ReactiveBase.
- If required, use
transformResponseprop to transform response in component-consumable format.
dataField
| Type | Optional |
|---|---|
String |
Yes |
data field to be connected to the component's UI view. It is useful for providing a sorting context i.e. results would be sorted based on the dataField.
vectorDataField
| Type | Optional |
|---|---|
String |
Yes |
vector data field to query for retrieving hits for the component's UI view. This is used when applying kNN search. Introduced in v4.3.0.
aggregationSize
To set the number of buckets to be returned by aggregations.
Note: This is a new feature and only available for appbase versions >= 7.41.0.
excludeFields
| Type | Optional |
|---|---|
String Array |
Yes |
fields to be excluded in search results.
includeFields
| Type | Optional |
|---|---|
String Array |
Yes |
fields to be included in search results.
pagination
| Type | Optional |
|---|---|
Boolean |
Yes |
pagination <> infinite scroll switcher. Defaults to false, i.e. an infinite scroll based view. When set to true, a pagination based list view with page numbers will appear.
infiniteScroll
| Type | Optional |
|---|---|
Boolean |
Yes |
Defaults to true, When set to true, an infinite scroll based view will appear.
paginationAt
| Type | Optional |
|---|---|
String |
Yes |
Determines the position where to show the pagination, only applicable when pagination prop is set to true. Accepts one of top, bottom or both as valid values. Defaults to bottom.
pages
| Type | Optional |
|---|---|
Number |
Yes |
number of user selectable pages to be displayed when pagination is enabled. Defaults to 5.
currentPage
| Type | Optional |
|---|---|
Number |
Yes |
can be used to set the default page number for initial render.
scrollOnChange
| Type | Optional |
|---|---|
Boolean |
Yes |
can be used to control the scroll to top behavior when new results found. Defaults to true.
sortBy
| Type | Optional |
|---|---|
String |
Yes |
sort the results by either asc or desc order. It is an alternative to sortOptions, both can't be used together.
sortOptions
| Type | Optional |
|---|---|
Object Array |
Yes |
an alternative to the sortBy prop, sortOptions creates a sorting view in the ReactiveList component's UI. Each array element is an object that takes three keys:
label- label to be displayed in the UI.dataField- data field to use for applying the sorting criteria on.sortBy- specified as eitherascordesc.
defaultSortOption
| Type | Optional |
|---|---|
String |
Yes |
accepts the label of the desired sort option to set default sort value from given sortOptions array.
size
| Type | Optional |
|---|---|
Number |
Yes |
number of results to show per view. Defaults to 10.
candidates
| Type | Optional |
|---|---|
Number |
Yes |
number of candidate values (aka k) to retrieve for kNN search. This is used with kNN search.
loader
| Type | Optional |
|---|---|
String|slot-scope |
Yes |
display to show the user while the data is loading, accepts String or JSX markup.
prevLabel
| Type | Optional |
|---|---|
String |
Yes |
Pagination previous button text. Defaults to Prev.
nextLabel
| Type | Optional |
|---|---|
String |
Yes |
Pagination next button text. Defaults to Next.
showResultStats
| Type | Optional |
|---|---|
Boolean |
Yes |
whether to show result stats in the form of results found and time taken. Defaults to true.
showEndPage
| Type | Optional |
|---|---|
Boolean |
Yes |
whether to show end pages in pagination. Defaults to false.
react
| Type | Optional |
|---|---|
Object |
Yes |
a dependency object defining how this component should react based on the state changes in the sensor components.
URLParams
| Type | Optional |
|---|---|
Boolean |
Yes |
when set adds the current page number to the url. Only works when pagination is enabled.
renderItem
| Type | Optional |
|---|---|
Function|slot-scope |
Yes |
returns a list element object to be rendered based on the res data object. This callback function prop or slot is called for each data item rendered in the ReactiveList component's view. For example,
<template #renderItem="{ item }">
<div>
<a class="full_row single-record single_record_for_clone" key="item._id">
<div class="text-container full_row" :style="{ paddingLeft: '10px' }">
<div class="text-head text-overflow full_row">
<span class="text-head-info text-overflow">
{{ item.name ? item.name : "" }} - {{ item.brand ? item.brand : "" }}
</span>
<span class="text-head-city">{{ item.brand ? item.brand : "" }}</span>
</div>
<div class="text-description text-overflow full_row">
<ul class="highlight_tags">
{{ item.price ? `Priced at $${{ item.price }}` : "Free Test Drive" }}
</ul>
</div>
</div>
</a>
</div>
</template>render
| Type | Optional |
|---|---|
Function|slot-scope |
Yes |
A function or slot returning the UI you want to render based on your results. This function receives a list of parameters and expects to return a JSX.
Read more about it here.
Note:
Either
renderItemorrenderis required in ReactiveList for rendering the data.
renderResultStats
| Type | Optional |
|---|---|
Function|slot-scope |
Yes |
renders custom result stats using a callback function that takes stats object as parameter and expects it to return a string or html. stats object contains following properties
numberOfResults:numberTotal number of results foundnumberOfPages:numberTotal number of pages found based on current page sizecurrentPage:numberCurrent page number for which data is being renderedtime:numberTime taken to find total results (in ms)displayedResults:numberNumber of results displayed in current viewhidden:numberTotal number of hidden results foundpromoted:numberTotal number of promoted results found
<template #renderResultStats="{ numberOfResults, time, displayedResults }">
<div>
Showing {{displayedResults}} of total {{numberOfResults}} in {{time}} ms
</div>
</template>renderError
| Type | Optional |
|---|---|
String|Function|slot-scope |
Yes |
can be used to render an error message in case of any error.
<template #renderError="error">
<div>Something went wrong!<br />Error details<br />{{ error }}</div>
</template>renderNoResults
| Type | Optional |
|---|---|
String|Function|slot-scope |
Yes |
show custom message or component when no results found.
defaultQuery
| Type | Optional |
|---|---|
Function |
Yes |
applies a default query to the result component. This query will be run when no other components are being watched (via React prop), as well as in conjunction with the query generated from the React prop. The function should return a query.
distinctField
| Type | Optional |
|---|---|
String |
Yes |
This prop returns only the distinct value documents for the specified field. It is equivalent to the DISTINCT clause in SQL. It internally uses the collapse feature of Elasticsearch. You can read more about it over here.
distinctFieldConfig
| Type | Optional |
|---|---|
Object |
Yes |
This prop allows specifying additional options to the distinctField prop. Using the allowed DSL, one can specify how to return K distinct values (default value of K=1), sort them by a specific order, or return a second level of distinct values. distinctFieldConfig object corresponds to the inner_hits key's DSL. You can read more about it over here.
index
| Type | Optional |
|---|---|
String |
Yes |
The index prop can be used to explicitly specify an index to query against for this component. It is suitable for use-cases where you want to fetch results from more than one index in a single ReactiveSearch API request. The default value for the index is set to the app prop defined in the ReactiveBase component.
<reactive-list
....
distinctField="authors.keyword"
:distinctFieldConfig="{
inner_hits: {
name: 'most_recent',
size: 5,
sort: [{ timestamp: 'asc' }],
},
max_concurrent_group_searches: 4,
}"
/>Sub Components
ResultCardsWrapper
A wrapper component for ResultCard components to render a card based layout.
Read more about the usage here.
ResultListWrapper
A wrapper component for ResultList components to render a list based layout.
Read more about the usage here.
Demo
Styles
ReactiveList component supports innerClass prop with the following keys:
resultsInfosortOptionsresultStatsnoResultsbuttonpaginationactivelistpoweredBy
Read more about it here.
Extending
ReactiveList component can be extended to
- customize the look and feel with
className, - render individual result data items using
renderItem, - render the entire result data using
render. - connect with external interfaces using
query-change.
<template>
<reactive-list className="custom-class" @query-change="handleQueryChange" />
</template>
<script>
export default {
name: 'app',
methods: {
handleQueryChange: (prevQuery, nextQuery) => {
// use the query with other js code
console.log('prevQuery', prevQuery);
console.log('nextQuery', nextQuery);
},
},
};
</script>className
| Type | Optional |
|---|---|
String |
Yes |
CSS class to be injected on the component container.
renderItem
| Type | Optional |
|---|---|
Function|slot-scope |
Yes |
a callback function or slot-scope where user can define how to render the view based on the data changes.
render
| Type | Optional |
|---|---|
Function |
Yes |
an alternative callback function or slot to renderItem, where user can define how to render the view based on all the data changes.
It accepts an object with these properties:
loading:booleanindicates that the query is still in progresserror:objectAn object containing the error infodata:arrayAn array of results obtained from combiningpromotedresults along with thehits.aggregationDataarrayAn array of aggregations buckets. Each bucket would have atop_hitsproperty if you're using Elasticsearch top hits aggregations indefaultQueryprop.promotedData:arrayAn array of promoted results obtained from the applied query. Read MoreNote:
dataandpromotedDataresults has a property called_click_idwhich can be used with triggerClickAnalytics to register the click analytics info.customDataobjectCustom data set in the query rule when appbase.io is used as backend. Read MorerawDataobjectAn object of raw response as-is from elasticsearch query.resultStats:objectAn object with the following properties which can be helpful to render custom stats:numberOfResults:numberTotal number of results foundnumberOfPages:numberTotal number of pages found based on current page sizecurrentPage:numberCurrent page number for which data is being renderedtime:numberTime taken to find total results (in ms)displayedResults:numberNumber of results displayed in current viewhidden:numberTotal number of hidden results foundpromoted:numberTotal number of promoted results found
loadMore:functionA callback function to be called to load the next page of results into the view. The callback function is only applicable in the case of infinite loading view (i.e.infiniteScrollprop set totrue).triggerClickAnalytics:functionA function which can be called to register a click analytics. Read MoresetPage:functionA function which will allow to dispatch a page change event when using custom pagination. It acceptspageNumberas its parameter.
<reactive-list>
<template #render="{ loading, error, data }">
<div>
<div v-if="loading">Fetching Results.</div>
<div v-if="Boolean(error)">Something went wrong! Error details {{JSON.stringify(error)}}</div>
<ul v-bind:key="result._id" v-for="result in data">
<li>
{{result.title}}
<!-- Render UI -->
</li>
</ul>
</div>
</template>
</reactive-list>Events
query-change
is an event which accepts component's **prevQuery** and **nextQuery** as parameters. It is called everytime the component's query changes. This event is handy in cases where you want to generate a side-effect whenever the component's query would change.page-change
called when the current page is changed. If not defined, `window` will be scrolled to the top of the page.page-click
accepts a function which is invoked with the updated page value when a pagination button is clicked. For example if 'Next' is clicked with the current page number as '1', you would receive the value '2' as the function parameter.data
| Type | Optional |
|---|---|
Function |
Yes |
gets triggered after data changes, which returns an object with these properties: `data`, `promotedData`, `rawData`, `customData` & `resultStats`.error
gets triggered in case of an error and provides the `error` object, which can be used for debugging or giving feedback to the user if needed.Note:
The fundamental difference between
page-changeandpage-clickis thatpage-clickis only called on a manual interaction with the pagination buttons, whereas,page-changewould also be invoked if some other side effects caused the results to update which includes updating filters, queries or changing pages. The behaviour of these two may change in the future versions as we come up with a better API.