# Search

## The `onSearch` callback

Whenever the Assistant detects that the user is searching for items in the app, it will try to break down the search request into its basic components and invoke the `onSearch` callback associated with the search user journey. The callback looks like this:

{% tabs %}
{% tab title="Android Native" %}

```
SearchAppState onSearch(SearchInfo searchInfo, SearchUserJourney userJourney);
```

{% endtab %}

{% tab title="React Native" %}

```
onSearch: async (searchInfo, searchUserJourney)
```

{% endtab %}

{% tab title="Flutter" %}

```dart
SearchAppState onSearch(SearchInfo searchInfo, SearchUserJourney searchUserJourney)
```

{% endtab %}

{% tab title="Web" %}

```
onSearch: async (searchInfo, searchUserJourney)
```

{% endtab %}

{% tab title="Android (Deprecated)" %}

```
// This is deprecated and is kept here for reference only

SearchUserJourney.AppState onSearch(SearchInfo searchInfo, SearchUserJourney userJourney);
```

{% endtab %}
{% endtabs %}

When this callback is invoked, the app is expected to:

1. Consume the details of the search request via the `SearchInfo` parameter.&#x20;
2. Fire the app's search request.
3. Finally, return the `AppState` along with the appropriate `Condition` corresponding to the state that the app transitioned into

For  example, for a given *`onSearch`* callback invocation, if the search completes successfully and the app transitions to a screen showing search results, the app would return the`AppState` as SEARCH\_RESULTS along with condition SUCCESS , as shown below:   &#x20;

{% tabs %}
{% tab title="Android Native" %}

```java
public SearchUserJourney.AppState onSearch(SearchInfo searchInfo, SearchUserJourney searchJourney) {
   // The searchItem will have the relevant part of the end-users search request 
   // and will automatically be in English, even if the user spoke in a 
   // different language. 
   String searchItem = searchInfo.getItem().getDescription();
   
   // Launch SearchResultsActivity using "searchItem"
   // ...
   
   return new SearchResultsAppState(SUCCESS);
}
```

{% endtab %}

{% tab title="React Native" %}

```javascript
onSearch: async (searchInfo, searchUserJourney) => {
  var searchItem = searchInfo.item.description;
   
  // Perform UI operation using "searchItem"
  // ...
  
  searchUserJourney.setSuccess();
  return SearchUserJourney.AppState.SEARCH_RESULTS;
},
```

{% endtab %}

{% tab title="Flutter" %}

```dart
@override
SearchAppState onSearch(SearchInfo searchInfo, SearchUserJourney searchUserJourney) {   
   String searchItem = searchInfo.item.description
   
   // Update SearchResultsWidget using "searchItem"
   // ...
   
   return new SearchResultAppState(SUCCESS);
}
```

{% endtab %}

{% tab title="Web" %}

```javascript
onSearch: async (searchInfo, searchUserJourney) => {
  const searchItem = searchInfo.item.description;
   
  // Perform operation using "searchItem"
  // ...
  
  searchUserJourney.setSuccess();
  return SearchUserJourney.AppState.SEARCH_RESULTS;
},
```

{% endtab %}
{% endtabs %}

## Sample Utterances that could trigger the search

The following are some examples of commands that could trigger this journey

* *"Onions"*
* *"Show me onions"*
* *"3 kgs of organic onions"*
* *"Looking for fresho organic onions"*
* *"Searching for Maggi Instant noodles in grocery"*
* *"2 rs head and shoulders shampoo"*

## `SearchInfo` Parameter

The parameter`SearchInfo`  contains the breakdown of the original search request. Its structure is as described below:&#x20;

{% tabs %}
{% tab title="Android Native" %}

```java
Class SearchInfo {
	public Item getItem();
	public List<FilterInfo> getFilters(); 
	public SortingInfo getSorting();
	public Boolean isAddToCart();
}

Class Item {
	public String getId(); // The ID of the item if set by the app or if Slang
	                       // was trained with it
	public String getCategory(); // The category that the user specified, 
	                             // eg "pharmacy" or "grocery"
	public String getBrand(); // The brand name identified by Slang from what the
	                          // user spoke
	public String getProductType();  // The product type if any as identified by Slang
	public String[] getVariants();   // The variants (like "organic") if any
	public String getDescrption();   // The helper method to get back a fully
	                                 // constructed search string from what the
	                                 // user spoke
	public Quantity getQuantity();   // The quantity if any is spoken by the user
	public Size getSize();           // The size if any is spoken by the user
	public Price getPrice();         // The price value if any spoken by the user
}
```

{% endtab %}

{% tab title="React Native" %}

```
// When the user searches for something like 
// 4 fresho organic onions 3kg
// This is how the SearchInfo parameter would be populated

{
  "isSmartSearch": false,
  "item": {
    "brand": "Fresho Organic",
    "description": "Fresho Organic",
    "completeDescription": "Fresho Organic 3 kg onion"
    "quantity": {
      "amount": 4,
      "unit": "UNKNOWN"
    },
    "size": {
      "amount": 3,
      "unit": "KILOGRAM"
    },
    "productNames": [
      "onions"
    ]
  },
  "isAddToCart": true
}
```

{% endtab %}

{% tab title="Flutter" %}

```dart
class SearchInfo {
  Item item;
  bool isAddToCart;
  SortingInfo sortingInfo;
  List<FilterInfo> filterInfoList;
}

class Item {
	String id; // The ID of the item if set by the app or if Slang was trained with it
	String category; // The category that the user specified, eg "pharmacy" or "grocery"
	String brand; // The brand name identified by Slang from what the user spoke
	String productType;  // The product type if any as identified by Slang
	List<String> productNames;   // The productNames (like "potato") if any
	String description;   // The helper method to get back a fully constructed search string from what the user spoke
	Quantity quantity;   // The quantity if any is spoken by the user
	Size size;           // The size if any is spoken by the user
	Price price;         // The price value if any spoken by the user
}

```

{% endtab %}

{% tab title="Web" %}

```
// When the user searches for something like 
// 3 fresho organic onions 2 rupees 3kg in grocery
// This is how the SearchInfo parameter would be populated

{
  "filterInfoList": [],
  "item": {
    "brand": "fresho organic",
    "category": "grocery",
    "description": "fresho organic onions",
    "id": null,
    "price": {
      "currency": "INR",
      "maxAmount": 3,
      "minAmount": 3
    },
    "productType": null,
    "quantity": {
      "amount": 2,
      "unit": "UNKNOWN"
    },
    "size": {},
    "variants": [
      "onions"
    ]
  },
  "isAddToCart": false,
  "sortingInfo": {}
}
```

{% endtab %}
{% endtabs %}

To illustrate, when the user says "*Search for fresho organic onions*", the following will be set in the Item object&#x20;

* *brand = "Fresho Organic"*
* *productNames = \["onion"]*
* *isAddedToCart = false*
* *completeDescription = "fresho organic onion"*

## Supported `AppState`s

The following `AppState`s are supported:

* **SEARCH\_RESULTS (`SearchResultsAppState`):** To be returned when the app performs a search and navigates to the search results screen. To indicate whether the search was successful or not, with a greater level of detail, please use the appropriate [conditions](https://docs.conva.ai/slang/getting-started/integrating-slang-retail-assistant/code-integration-basic-steps/code-integration-basic-steps-1/supported-user-journeys/..#supported-appstate-conditions).&#x20;
* **ADD\_TO\_CART (`AddToCartAppState`)**: To be returned when the app performs an add-to-cart action. To indicate whether the add to cart was successful or not, with a greater level of detail, please use the appropriate [conditions](https://docs.conva.ai/slang/getting-started/integrating-slang-retail-assistant/code-integration-basic-steps/code-integration-basic-steps-1/supported-user-journeys/..#supported-appstate-conditions).
* **UNSUPPORTED (`UnsupportedAppState`):** To be returned when the app is not ready to handle search yet. The Assistant will let the user know that the search is not yet supported by the app.

{% hint style="info" %}
The Slang Retail Assistant provides a special `AppState`**`WAITING`** that is common across all `UserJourney` types for completing asynchronous operations within the callback. Refer to the [Asynchronous Action Handling](https://docs.conva.ai/slang/advanced-topics/asynchronous-action-handling) section for details of how to deal with asynchronous operations.
{% endhint %}

### Supported Conditions

The following conditions are supported for each of the `AppState`s supported by the Assistant

<table data-header-hidden><thead><tr><th width="236.83976778273757">App State</th><th width="244.75173122968906">App State Condition</th></tr></thead><tbody><tr><td><strong>App State</strong></td><td><strong>App State Condition</strong></td></tr><tr><td><p><strong>SEARCH_RESULTS</strong> </p><p><strong>(<code>SearchResultsAppState</code>)</strong></p></td><td><p><em><strong>TERMINAL CONDITIONS</strong></em></p><p>      </p><p><strong><code>SUCCESS</code></strong></p><p>       The search was successful</p><p><strong><code>ITEM_NOT_FOUND</code></strong></p><p>       The item being searched could not be </p><p>       found</p><p><strong><code>ITEM_OUT_OF_STOCK</code></strong></p><p>        The item being searched is out of stock</p><p><strong><code>FAILURE</code></strong></p><p>        There was a failure while searching</p><p></p><p><em><strong>NON-TERMINAL CONDITIONS</strong></em></p><p>      </p><p><strong><code>ITEM_NOT_SPECIFIED</code></strong></p><p>       The item that needs to be searched has </p><p>       not been specified.</p></td></tr></tbody></table>

| **App State**                                                                                  | **App State Condition**                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| <p><strong>ADD\_TO\_CART</strong> </p><p><strong>(<code>AddToCartAppState</code>)</strong></p> | <p><em><strong>TERMINAL CONDITIONS</strong></em></p><p>      </p><p><strong><code>SUCCESS</code></strong></p><p>       The search was successful</p><p><strong><code>ITEM\_NOT\_FOUND</code></strong></p><p>       The item being searched could not be </p><p>       found</p><p><strong><code>ITEM\_OUT\_OF\_STOCK</code></strong></p><p>        The item being searched is out of stock</p><p><strong><code>FAILURE</code></strong></p><p>        There was a failure while searching</p><p></p><p><em><strong>NON-TERMINAL CONDITIONS</strong></em></p><p>      </p><p><strong><code>ITEM\_NOT\_SPECIFIED</code></strong></p><p>       The item that needs to be searched has </p><p>       not been specified.</p><p><strong><code>ITEM\_AMBIGUOUS</code></strong></p><p>      There are multiple items available for </p><p>       the current searched item and has to be </p><p>       disambiguated.</p><p><strong><code>ITEM\_AMBIGUOUS\_FORCE\_UI</code></strong></p><p>       Stop the voice disambiguation process </p><p>        and choose the item via the UI/Touch </p><p>        interface.</p><p><strong><code>ITEM\_QUANTITY\_REQUIRED</code></strong></p><p>        Quantity for the current item has to be </p><p>        specified.</p> |

For example, to indicate to the Assistant that the particular item being searched was not found by the app, the app should do the following:

{% tabs %}
{% tab title="Android Native" %}

```
public SearchUserJourney.AppState onSearch(SearchInfo searchInfo, SearchUserJourney searchJourney) {
   String searchItem = searchInfo.getItem().getDescription();
   
   // Launch SearchResultsActivity using "searchItem"
   // ...
   
   return new SearchResultsAppState(ITEM_NOT_FOUND);
}
```

{% endtab %}

{% tab title="React Native" %}

```javascript
onSearch: async (searchInfo, searchUserJourney) => {
  var searchItem = searchInfo.item.description;
   
  // Perform UI operation using "searchItem"
  // ...
  
  searchUserJourney.setSuccess();
  return SearchUserJourney.AppState.SEARCH_RESULTS;
},
```

{% endtab %}

{% tab title="Flutter" %}

```dart
SearchAppState onSearch(SearchInfo searchInfo, SearchUserJourney searchUserJourney) {
   String searchItem = searchInfo.item.description
   
   // Update SearchResultsWidget using "searchItem"
   // ...
   
   return new SearchResultsAppState(ITEM_NOT_FOUND);
}
```

{% endtab %}

{% tab title="Web" %}

```
onSearch: async (searchInfo, searchUserJourney) => {
  var searchItem = searchInfo.item.description;
   
  // Perform UI operation using "searchItem"
  // ...
  
  searchUserJourney.setSuccess();
  return SearchUserJourney.AppStates.SEARCH_RESULTS;
},
```

{% endtab %}

{% tab title="Android (Deprecated)" %}

```java
public SearchUserJourney.AppState onSearch(SearchInfo searchInfo, SearchUserJourney searchJourney) {
   String searchItem = searchInfo.getItem().getDescription();
   
   // Launch SearchResultsActivity using "searchItem"
   // ...
   
   userJourney.setItemNotFound();
   return SearchUserJourney.AppState.SEARCH_RESULTS;
}
```

{% endtab %}
{% endtabs %}

## Assistant Prompts

Based on the App State and the Condition that was set, the Assistant will speak out an appropriate message to the user. You can examine the default set of prompts configured for the Assistant through the Console and also customize it to your needs. Refer to the [Customizing the Assistant](https://docs.conva.ai/slang/getting-started/integrating-slang-retail-assistant/code-integration-basic-steps/code-integration-basic-steps-1/supported-user-journeys/broken-reference) section for details.&#x20;
