Overview
The CometChat Angular UIKit uses a Hybrid Approach for managing active chat state. At its core,ChatStateService acts as a single source of truth for the currently active chat entity — a CometChat.User, CometChat.Group, or CometChat.Conversation.
The Hybrid Approach gives you two ways to wire components:
- Service-based (default) — Components automatically subscribe to
ChatStateServiceand react when the active entity changes. No prop passing required. - Props override — Pass
[user]or[group]via@Input()bindings to override the service state for a specific component instance.
ChatStateService is provided at the root level (providedIn: 'root') and exposes both Angular Signals and RxJS Observables, so you can choose whichever reactive API fits your codebase.
Decision Matrix
Use this table to decide which pattern fits your use case:Service-Based Pattern
With the service-based pattern, you place Chat-Aware Components in your template and they automatically subscribe toChatStateService. When a user selects a conversation, the service updates and all downstream components react — no explicit binding needed.
<cometchat-conversations>callsChatStateService.setActiveConversation()when a conversation is clickedsetActiveConversation()extracts theCometChat.UserorCometChat.Groupfrom the conversation and sets it as the active entity<cometchat-message-header>,<cometchat-message-list>, and<cometchat-message-composer>automatically subscribe to the active user/group and update their UI
Props-Based Pattern
With the props-based pattern, you manage state yourself and pass[user] or [group] directly to each component via @Input() bindings. This gives you full control over which entity each component displays.
When
[user] or [group] @Input() bindings are provided, they take priority over
ChatStateService state for that component instance. Other component instances without
explicit bindings continue to read from the service.Mutual Exclusivity
ChatStateService enforces that only one chat entity — a CometChat.User or a CometChat.Group — can be active at any given time:
- Calling
setActiveUser(user)with a non-null value automatically setsactiveGrouptonull - Calling
setActiveGroup(group)with a non-null value automatically setsactiveUsertonull - Calling
setActiveConversation(conversation)extracts the entity and delegates tosetActiveUser()orsetActiveGroup(), applying the same rule - Calling
clearActiveChat()resets all state tonull
Advanced Patterns
Multi-Panel Chat Layouts
For applications that display multiple chat panels side by side (e.g., a support dashboard), use the props-based pattern to give each panel its own independent state:Each panel receives its own
[user] or [group] binding, so they operate independently
of ChatStateService. This avoids the mutual exclusivity constraint that applies to
service-based state.Programmatic Navigation
UseChatStateService to programmatically switch the active chat — for example, when navigating from a notification or deep link:
Cleanup via clearActiveChat()
Call clearActiveChat() to reset all active state when the user logs out, navigates away from the chat interface, or closes a chat window:
Scoping Customization Services for Multiple Instances
The sections above coverChatStateService and how to use props to give each panel its own data. But there’s a related concern: customization services like MessageBubbleConfigService and FormatterConfigService are also root-level singletons. If you configure custom bubble templates or formatters globally, those customizations apply to every message list in the app.
When you need different customizations per panel (e.g., a main chat with full bubble styling and a thread panel with minimal styling), use Angular’s hierarchical dependency injection to scope the service:
See CometChatMessageList — Multiple Message Lists with Different Configurations for a complete example with two panels.
Related Resources
- ChatStateService API Reference — Full API documentation for signals, observables, setters, getters, and mutual exclusivity behavior
- CometChatConversations — Conversation list component that calls
setActiveConversation()on selection - CometChatMessageHeader — Message header that subscribes to
activeUser/activeGroup - CometChatMessageList — Message list that subscribes to
activeUser/activeGroup - CometChatMessageComposer — Message composer that subscribes to
activeUser/activeGroup - CometChatUsers — User list that calls
setActiveUser()on selection - CometChatGroups — Group list that calls
setActiveGroup()on selection - CometChatGroupMembers — Group members list that subscribes to
activeGroup