Custom data

Data of your own can go out with a message, such as a priority flag, or stay in the composer for your UI only, such as whether a picker is open. The custom data manager, messageComposer.customDataManager, keeps both kinds.

Info:

Example

The user marks a message as urgent before sending it:

  1. The UI calls CustomDataManager.setMessageData({ priority: "high" }).
  2. The user sends the message. It goes out with custom: { priority: "high" }, and the copy in the message list shows the flag at once.
  3. The composer clears itself, and the next message starts without the flag.

What it holds

The custom data manager's state is in customDataManager.state. It has two fields, both empty objects at first:

Field What it holds Sent with the message Getter Setter
message Data that goes out with the message. yes, merged into the message's custom field customDataManager.customMessageData CustomDataManager.setMessageData()
custom Data for your UI, such as whether a picker is open. never customDataManager.customComposerData CustomDataManager.setCustomData()

Declare the fields you use in the CustomMessageData and CustomMessageComposerData interfaces, as Data conventions explains:

import "stream-chat";

declare module "stream-chat" {
  interface CustomMessageData {
    priority?: "high" | "normal";
  }

  interface CustomMessageComposerData {
    priorityPickerOpen?: boolean;
  }
}

Setting data

To... Call What happens
send data with the message CustomDataManager.setMessageData(data) Merges data into the message field of customDataManager.state.
keep data for your UI CustomDataManager.setCustomData(data) Merges data into the custom field of customDataManager.state.

Both merge at the top level: a key you pass replaces the value it had, and the other keys stay. When the composer is cleared, for example after a send, both fields start empty again.

const { customDataManager } = channel.messageComposer;

customDataManager.setCustomData({ priorityPickerOpen: true });
customDataManager.setMessageData({ priority: "high" });

How the data goes into the message

When the message is built, the fields of the message field of customDataManager.state are merged into the message's custom field: both in the request the server receives and in the copy the message list shows before the server answers. A draft saves them in its custom field too.

  • Loading restores it. When a draft or a message to edit is loaded into the composer, the message field of customDataManager.state gets a copy of the draft's or the message's custom. The custom field starts empty, because its data is never sent.
  • Polls. A message that carries only a poll carries no custom data, as Polls explains.
  • Edits. An edit keeps the fields the message has in custom. CustomDataManager.setMessageData() merges new values into them. To remove fields, set the message field of customDataManager.state to the fields to keep: customDataManager.state.partialNext({ message: { reviewed: true } }). An empty object removes them all, and the edit then sends an empty custom.
Info:

Example

A message has custom: { priority: "high", reviewed: true }. The user edits it:

  1. The edit starts, and customDataManager.customMessageData holds both fields.
  2. The UI calls CustomDataManager.setMessageData({ priority: "low" }).
  3. The user saves. The message now has custom: { priority: "low", reviewed: true }.

To add data that's worked out when the message is sent, use a composition middleware instead, and write the data into the custom field of both the request and the local copy. Composer middleware shows how to add one.

Settings

The custom data manager has no settings.

Used in