I am building an angular chat application using Sendbird. I followed this build an angular chat app using sendbird Please refer to the above link first.
After establishing a Connection I am getting an Error while connecting using WebSocket Connection. But even after getting errors, I can get the Last Message but, the messages and groups are not getting updated.
Sending the component file below.
import { Component, OnInit } from '@angular/core';
// import SendBird from 'sendbird';
import { ChatsService } from './services/chats.service';
import SendBird, { GroupChannelCollection } from 'sendbird';
@Component({
selector: 'app-chats',
templateUrl: './chats.component.html',
styleUrls: ['./chats.component.scss'],
})
export class ChatsComponent implements OnInit {
userData = JSON.parse(localStorage.getItem('userDataIA') || '{}');
userId = this.userData.User.Id.toString();
chatBox = false;
callback: any;
OpenChannel: any;
GroupChannel: any;
connected = false;
startConversationResult: string;
conversations: Array<SendBird.GroupChannel> | any | null;
listConversationsResult: string | null;
selectedChannel: any;
messages: any;
textMessage: any;
currentDate: Date = new Date();
usersList: any;
OtherUserId: any;
sb: SendBird.SendBirdInstance;
constructor(
private chatsService: ChatsService
) { }
async ngOnInit(): Promise<void> {
this.chatsService.init();
await this.connect();
this.getMyConversations();
this.registerEventHandlers();
this.getUsers();
}
ContactsConversations:any = [
];
getSendBirdConfig() {
this.chatsService.sendBirdConfig().subscribe({
next: ((response) => {
if (response['Status'] === 'Success') {
this.chatsService.APP_ID = response['Data'].AppId;
this.chatsService.api_token = response['Data'].ApiToken;
}
if (response['Status'] === 'Error') {
if (response['ErrorCode'] === 'INTERNAL_SERVER_ERROR') {
console.log(error);
return;
}
}
})
});
}
async connect() {
await this.chatsService.connect(
this.userId,
(user: any,error: any ) => {
console.log(user,error);
if(user) {
this.connected = true;
this.registerEventHandlers();
console.log(this.connected, 'connected');
}
}
);
}
registerEventHandlers() {
this.chatsService.registerEventHandlers(
'123',
(data: { event: string; data: any }) => {
console.log('New event: ' + data.event, data.data);
if (this.selectedChannel) {
if (data.event == 'onMessageReceived' && this.messages) {
if (data.data.channel.url == this.selectedChannel.url) {
this.messages.push(data.data.message);
}
}
}
}
);
}
getUsers(){
const userListQuery = this.chatsService.sb.createApplicationUserListQuery();
userListQuery.next((users, error) => {
if (error) {
console.error('Error retrieving user list:', error);
} else {
// Users retrieved successfully
this.usersList = users;
console.log('User list:', this.usersList);
}
});
}
startConversation() {
const channelName = 'Demo Channel';
const userIds = [this.userId, this.OtherUserId];
this.chatsService.createGroupChannel(
channelName,
userIds,
(error: SendBird.SendBirdError, groupChannel: SendBird.GroupChannel) => {
if (error) {
this.startConversationResult = 'Error creating the conversation';
} else {
this.startConversationResult = 'Conversation created';
this.getMyConversations();
}
}
);
}
getMyConversations() {
this.chatsService.getMyGroupChannels(
(
error: SendBird.SendBirdError,
groupChannels: Array<SendBird.GroupChannel>
) => {
if (error) {
this.listConversationsResult = 'Unable to get your conversations';
console.log(this.listConversationsResult);
} else {
this.conversations = groupChannels;
console.log(this.conversations);
this.getMessages(this.selectedChannel);
}
}
);
console.log('Getting Conversations');
}
onUserClick() {
this.getMessages(this.selectedChannel);
this.chatBox = true;
}
getMessages(channel: SendBird.GroupChannel) {
this.selectedChannel = channel;
this.chatsService.getMessagesFromChannel(
channel,
(
error: SendBird.SendBirdError,
messages: Array<
SendBird.UserMessage | SendBird.FileMessage | SendBird.AdminMessage
>
) => {
if (!error) {
this.messages = messages;
}
}
);
}
sendMessage() {
this.chatsService.sendMessage(
this.selectedChannel,
this.textMessage,
(error: SendBird.SendBirdError, userMessage: SendBird.UserMessage) => {
this.getMessages(this.selectedChannel);
}
);
}
}
The Service File Looks Like this
import { Injectable } from '@angular/core';
import SendBird from 'sendbird';
import { environment } from 'src/environments/environment';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { map, catchError, throwError } from 'rxjs';
@Injectable({
providedIn: 'root',
})
export class ChatsService {
public sb: SendBird.SendBirdInstance;
api_token: string;
APP_ID: string;
BASE_URL = environment.API_URL;
Data = JSON.parse(localStorage.getItem('userData') || '');
Token = this.Data.AuthToken;
entityId: any = localStorage.getItem('entity');
options = { headers: new HttpHeaders().set('authorization', `BEARER ${this.Token}`) };
constructor(public httpClient: HttpClient) {
}
sendBirdConfig() {
const API_URL = `${this.BASE_URL}send-bird/configs`;
return this.httpClient.get(API_URL, this.options).pipe(
map((data: any) => {
this.APP_ID = data.Data.AppId;
this.api_token = data.Data.ApiToken;
return data;
}),
catchError(error => {
return throwError(() => error);
})
);
}
init() {
this.sb = new SendBird({ appId: this.APP_ID });
SendBird.setLogLevel(SendBird.LogLevel.ERROR);
}
connect(userId: any, callback: any) {
this.sb.connect(userId, (user: any, error: any) => {
callback(user, error);
});
}
isConnected() {
return this.sb && this.sb.currentUser && this.sb.currentUser.userId;
}
getConnectedUser() {
return this.sb && this.sb.currentUser ? this.sb.currentUser : null;
}
registerEventHandlers(UNIQUE_HANDLER_ID: string, callback: any) {
const channelHandler = new this.sb.ChannelHandler();
channelHandler.onMessageReceived = (channel: any, message: any) => {
console.log('received Message');
callback({
event: 'onMessageReceived',
data: {
channel,
message,
},
});
};
channelHandler.onMentionReceived= (channel: any, message: any) => {
console.log('received Mention');
callback({
event: 'onMentionReceived',
data: {
channel,
message,
},
});
};
channelHandler.onTypingStatusUpdated = (channel: any) => {
console.log('Typing Status');
callback({
event: 'onTypingStatusUpdated',
data: {
channel
},
});
};
channelHandler.onUserEntered = (channel: any, user: any) => {
console.log('User Entered');
callback({
event: 'onUserEntered',
data: {
channel,
user,
},
});
};
channelHandler.onUserJoined = (channel: any, user: any) => {
console.log('User Joined');
callback({
event: 'onUserJoined',
data: {
channel,
user,
},
});
};
channelHandler.onUserLeft = (channel: any, user: any) => {
console.log('User Left');
callback({
event: 'onUserLeft',
data: {
channel,
user,
},
});
};
}
createUser(userId: string, nickname: string): Promise<any> {
return new Promise((resolve, reject) => {
this.sb.connect(userId, (user, error) => {
if (error) {
reject(error);
}
});
});
}
createGroupChannel(
channelName: string,
userIds: Array<string>,
callback: any
) {
const params = new this.sb.GroupChannelParams();
// params.addUserIds();
params.addUserIds(userIds);
params.name = channelName;
this.sb.GroupChannel.createChannel(
params,
(groupChannel: SendBird.GroupChannel, error: SendBird.SendBirdError) => {
callback(error, groupChannel);
}
);
}
getMyGroupChannels(callback: any) {
const listQuery = this.sb.GroupChannel.createMyGroupChannelListQuery();
listQuery.includeEmpty = true;
listQuery.memberStateFilter = 'joined_only';
listQuery.order = 'latest_last_message';
listQuery.limit = 15; // The value of pagination limit could be set up to 100.
if (listQuery.hasNext) {
listQuery.next((groupChannels: any, error: any) => {
callback(error, groupChannels);
});
}
}
getMessagesFromChannel(groupChannel: SendBird.GroupChannel, callback: any) {
const listQuery = groupChannel.createPreviousMessageListQuery();
listQuery.limit = 10;
listQuery.includeMetaArray = true;
// Retrieving previous messages.
listQuery.load((messages, error) => {
callback(error, messages);
});
}
sendMessage(
channel: SendBird.GroupChannel | SendBird.OpenChannel,
message: string,
callback: any
) {
const params = new this.sb.UserMessageParams();
params.message = message;
channel.sendUserMessage(params, (userMessage, error) => {
callback(error, userMessage);
});
}
}
I am getting all the relevant data by calling the functions but can not get the values dynamically, i.e. for every new message/group I have to refresh my page and call the APIs again. It should work as any other real-time chat application works. I am having problems using Event Handler and using the Websocket connection. Please review it.