> ## Documentation Index
> Fetch the complete documentation index at: https://cometchat-22654f5b-docs-rn-guide-message-privately.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# ViewModel & Data

> Access and configure the ViewModel layer to customize data fetching, filtering, and state management.

Each component's ViewModel manages data fetching, state transitions, and business logic via `LiveData`. You can access it to configure request parameters, observe state changes, or manipulate the data list directly.

## Accessing the ViewModel

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    val conversations = CometChatConversations(context)
    val viewModel: ConversationsViewModel = conversations.getViewModel()
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    CometChatConversations conversations = new CometChatConversations(context);
    ConversationsViewModel viewModel = conversations.getViewModel();
    ```
  </Tab>
</Tabs>

## Configuring Data Fetching with RequestBuilders

Use `setConversationsRequestBuilder` to control what data the component fetches. The builder accepts SDK parameters like limits, tags, and filters.

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    // Filter conversations by tags and limit to 20 results
    val builder = ConversationsRequest.ConversationsRequestBuilder()
        .setLimit(20)
        .setTags(listOf("important", "pinned"))
        .withTags(true)

    conversations.setConversationsRequestBuilder(builder)
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    // Filter conversations by tags and limit to 20 results
    ConversationsRequest.ConversationsRequestBuilder builder =
        new ConversationsRequest.ConversationsRequestBuilder()
            .setLimit(20)
            .setTags(Arrays.asList("important", "pinned"))
            .withTags(true);

    conversations.setConversationsRequestBuilder(builder);
    ```
  </Tab>
</Tabs>

<Warning>
  Pass the builder object, not the result of `.build()`. The component calls `.build()` internally.
</Warning>

## LiveData Observables

The ViewModel exposes `LiveData` observables you can observe for custom logic:

| Observable                     | Type                                          | Description                                                    |
| ------------------------------ | --------------------------------------------- | -------------------------------------------------------------- |
| `getMutableConversationList()` | `MutableLiveData<List<Conversation>>`         | The current list of conversations                              |
| `getStates()`                  | `MutableLiveData<UIKitConstants.States>`      | Component state (LOADING, LOADED, EMPTY, ERROR)                |
| `insertAtTop()`                | `MutableLiveData<Integer>`                    | Emits the index when a new conversation is inserted at the top |
| `moveToTop()`                  | `MutableLiveData<Integer>`                    | Emits the index when a conversation moves to the top           |
| `updateConversation()`         | `MutableLiveData<Integer>`                    | Emits the index when a conversation is updated                 |
| `remove()`                     | `MutableLiveData<Integer>`                    | Emits the index when a conversation is removed                 |
| `progressState()`              | `MutableLiveData<UIKitConstants.DeleteState>` | Tracks delete operation progress                               |
| `playSound()`                  | `MutableLiveData<Boolean>`                    | Triggers when a new message sound should play                  |
| `getCometChatException()`      | `MutableLiveData<CometChatException>`         | Emits errors from the SDK                                      |

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    val viewModel = conversations.getViewModel()

    // Observe state changes
    viewModel.getStates().observe(lifecycleOwner) { state ->
        when (state) {
            UIKitConstants.States.LOADING -> { /* show custom loading */ }
            UIKitConstants.States.LOADED -> { /* data ready */ }
            UIKitConstants.States.EMPTY -> { /* no conversations */ }
            UIKitConstants.States.ERROR -> { /* handle error */ }
        }
    }

    // Observe the conversation list
    viewModel.getMutableConversationList().observe(lifecycleOwner) { list ->
        // React to list changes
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    ConversationsViewModel viewModel = conversations.getViewModel();

    // Observe state changes
    viewModel.getStates().observe(lifecycleOwner, state -> {
        if (state == UIKitConstants.States.LOADING) {
            // show custom loading
        } else if (state == UIKitConstants.States.LOADED) {
            // data ready
        }
    });

    // Observe the conversation list
    viewModel.getMutableConversationList().observe(lifecycleOwner, list -> {
        // React to list changes
    });
    ```
  </Tab>
</Tabs>

## Mutation Methods

The ViewModel provides methods to programmatically manipulate the data list:

| Method                             | Description                           |
| ---------------------------------- | ------------------------------------- |
| `addList(List<Conversation>)`      | Append a list of conversations        |
| `remove(Conversation)`             | Remove a specific conversation        |
| `remove(int index)`                | Remove a conversation by index        |
| `update(Conversation, boolean)`    | Update a conversation in the list     |
| `refreshList()`                    | Clear and re-fetch from the server    |
| `clear()`                          | Clear all conversations from the list |
| `fetchConversation()`              | Fetch the next page of conversations  |
| `deleteConversation(Conversation)` | Delete a conversation via the SDK     |

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    val viewModel = conversations.getViewModel()

    // Refresh the entire list
    viewModel.refreshList()

    // Remove a specific conversation
    viewModel.remove(conversation)

    // Clear all data
    viewModel.clear()
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    ConversationsViewModel viewModel = conversations.getViewModel();

    // Refresh the entire list
    viewModel.refreshList();

    // Remove a specific conversation
    viewModel.remove(conversation);

    // Clear all data
    viewModel.clear();
    ```
  </Tab>
</Tabs>

## Lifecycle Callbacks

Intercept data loading lifecycle events with these callbacks on the View:

| Callback                          | Triggered When                       |
| --------------------------------- | ------------------------------------ |
| `setOnLoad(OnLoad<Conversation>)` | Data has been successfully loaded    |
| `setOnEmpty(OnEmpty)`             | The data list is empty after loading |

<Tabs>
  <Tab title="Kotlin">
    ```kotlin theme={null}
    conversations.setOnLoad { list ->
        // Called when conversations are loaded
        Log.d("Conversations", "Loaded ${list.size} conversations")
    }

    conversations.setOnEmpty {
        // Called when no conversations exist
        Log.d("Conversations", "No conversations found")
    }
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    conversations.setOnLoad(list -> {
        // Called when conversations are loaded
        Log.d("Conversations", "Loaded " + list.size() + " conversations");
    });

    conversations.setOnEmpty(() -> {
        // Called when no conversations exist
        Log.d("Conversations", "No conversations found");
    });
    ```
  </Tab>
</Tabs>

## Related

* [Adapter Customization](/ui-kit/android/customization-adapters) — Manipulate list data at the adapter level.
* [Customization Overview](/ui-kit/android/customization-overview) — See all customization categories.
