Vue Chat - Data Binding
You can bind data to Chat in two ways: with the items array or the dataSource entity.
items
The items array contains all messages in the Chat. To display an initial message, add it to this array. Add subsequent messages to the array to render them in Chat.
jQuery
$(() => { $('#chat').dxChat({ // ... items: [ { timestamp: Date.now(), author: secondUser, text: "Hello! I'm here to help you. How can I assist you today?", } ]; onMessageEntered: (e) => { e.component.renderMessage(e.message); }, }); });
Angular
<dx-chat [items]="messages" (onMessageEntered)="onMessageEntered($event)" ></dx-chat>
import { DxChatTypes } from "devextreme-angular/ui/chat"; // ... export class AppComponent { messages: DxChatTypes.Message[] = [ { timestamp: Date.now(), author: secondUser, text: "Hello! I'm here to help you. How can I assist you today?", } ]; onMessageEntered({ message }) { this.messages = [...this.messages, message]; } }
Vue
<template> <DxChat :items="messages" @message-entered="onMessageEntered" /> </template> <script setup> import DxChat from "devextreme-vue/chat"; const messages = [ { timestamp: Date.now(), author: secondUser, text: "Hello! I'm here to help you. How can I assist you today?", } ]; const onMessageEntered = ({ message }) => { messages.value = [...messages.value, message]; }; </script>
React
import React, { useCallback, useState } from "react"; import Chat from "devextreme-react/chat"; const initialMessage = { timestamp: Date.now(), author: secondUser, text: "Hello! I'm here to help you. How can I assist you today?", }; const App = () => { const [messages, setMessages] = useState(initialMessage); const onMessageEntered = useCallback(({ message }) => { setMessages((prevMessages) => [...prevMessages, message]); }, []); return ( <Chat onMessageEntered={onMessageEntered} items={messages} /> ); };
dataSource
For a more flexible solution than one achieved with the use of an array, specify the dataSource property. For instance, with dataSource, Chat can handle server-side data processing through Web API, a store, or a DataSource object.
When you pass a store to dataSource, the DataSource instance is created automatically inside the Chat.
When you use dataSource, the reloadOnChange property is crucial:
- When you send a message in a Chat (press the "Send" button), the Chat triggers the store's insert method and adds the message to the store.
- If reloadOnChange is enabled (default), the dataSource reloads: clears all items and calls the load method to update itself. Chat automatically listens to dataSource changes, and updates the message feed with new messages.
- Disable reloadOnChange to manage large numbers of messages, prevent additional load requests, and control message rendering timing.
The following code snippet includes:
- A CustomStore.
- A DataSource (pagination disabled).
- Push API for inserting and updating messages.
reloadOnChange: false
.
jQuery
const messages = [ { timestamp: new Date(), text: "Hello! I'm here to help you. How can I assist you today?" } ]; let uniqueIndex = messages.length + 1; let editing = null; $(() => { const customStore = new DevExpress.data.CustomStore({ key: "id", load: () => { const d = $.Deferred(); setTimeout(() => { d.resolve([...messages]); }); return d.promise(); }, insert: (message) => { const d = $.Deferred(); setTimeout(() => { messages.push(message); d.resolve(); }); return d.promise(); }, }); const dataSource = new DevExpress.data.DataSource({ store: customStore, paginate: false }); $("#chat").dxChat({ dataSource, reloadOnChange: false, onMessageEntered: (e) => { if (editing) { dataSource.store().push([{ type: "update", key: editing, data: { text: e.message.text } }]); editing = null; } else { dataSource.store().push([ { type: "insert", data: { id: uniqueIndex++, ...e.message } } ]); } }, }); });
Angular
<dx-chat [dataSource]="dataSource" [reloadOnChange]="false" (onMessageEntered)="onMessageEntered($event)"> </dx-chat>
import DataSource from 'devextreme/data/data_source'; import CustomStore from 'devextreme/data/custom_store'; import { DxChatTypes } from "devextreme-angular/ui/chat"; // ... export class AppComponent { messages: DxChatTypes.Message[] = [{ timestamp: new Date(), text: "Hello! I'm here to help you. How can I assist you today?" }]; customStore: CustomStore = new CustomStore({ key: "id", load: () => { return new Promise((resolve) => { setTimeout(() => { resolve([...this.messages]); }, 0); }); }, insert: (message) => { return new Promise((resolve) => { setTimeout(() => { this.messages.push(message); resolve(message); }); }); }, }); dataSource: DataSource = new DataSource({ store: this.customStore, paginate: false, }); editing = null; uniqueIndex = this.messages.length + 1; onMessageEntered(e: DxChatTypes.MessageEnteredEvent) { if (this.editing) { this.dataSource.store().push([{ type: "update", key: this.editing, data: { text: e.message.text } }]); this.editing = null; } else { this.dataSource.store().push([ { type: "insert", data: { id: this.uniqueIndex++, ...e.message } } ]); } }; }
Vue
<template> <DxChat :data-source="dataSource" :reload-on-change="false" @message-entered="onMessageEntered" /> </template> <script setup lang="ts"> import { DxChat } from 'devextreme-vue'; import type { DxChatTypes } from 'devextreme-vue/chat'; import DataSource from 'devextreme/data/data_source'; import CustomStore from 'devextreme/data/custom_store'; const messages: DxChatTypes.Message[] = [{ timestamp: new Date(), text: "Hello! I'm here to help you. How can I assist you today?" }]; const customStore = new CustomStore({ key: "id", load: () => { return new Promise((resolve) => { setTimeout(() => { resolve([...messages]); }, 0); }); }, insert: (message) => { return new Promise((resolve) => { setTimeout(() => { messages.push(message); resolve(message); }); }); }, }); const dataSource = new DataSource({ store: customStore, paginate: false, }); let editing = null; let uniqueIndex = messages.length + 1; const onMessageEntered = (e: DxChatTypes.MessageEnteredEvent) => { if (editing) { dataSource.store().push([{ type: "update", key: editing, data: { text: e.message.text } }]); editing = null; } else { dataSource.store().push([ { type: "insert", data: { id: uniqueIndex++, ...e.message } } ]); } }; </script>
React
import { Chat } from "devextreme-react"; import { ChatTypes } from "devextreme-react/chat"; import "devextreme/dist/css/dx.light.css"; import { useCallback } from "react"; import DataSource from "devextreme/data/data_source"; import CustomStore from "devextreme/data/custom_store"; export default function App() { const messages: ChatTypes.Message[] = [ { timestamp: new Date(), text: "Hello! I'm here to help you. How can I assist you today?", }, ]; const customStore = new CustomStore({ key: "id", load: (): Promise<ChatTypes.Message[]> => new Promise((resolve) => { setTimeout(() => { resolve([...messages]); }, 0); }), insert: (message: ChatTypes.Message): Promise<ChatTypes.Message> => new Promise((resolve) => { setTimeout(() => { messages.push(message); resolve(message); }); }), }); const dataSource = new DataSource({ store: customStore, paginate: false, }); let editing = null; let uniqueIndex = messages.length + 1; const onMessageEntered = useCallback((e: ChatTypes.MessageEnteredEvent) => { if (editing) { dataSource.store().push([ { type: "update", key: editing, data: { text: e.message!.text } }, ]); editing = null; } else { dataSource.store().push([{ type: "insert", data: { id: uniqueIndex++, ...e.message } }]); } }, []); return ( <Chat dataSource={dataSource} reloadOnChange={false} onMessageEntered={onMessageEntered} /> ); }
If you have technical questions, please create a support ticket in the DevExpress Support Center.