GetStream / stream-chat-js

JS / Browser Client - Build Chat with GetStream.io
https://getstream.io/chat/
Other
182 stars 76 forks source link

Typing issue regarding Immutable #596

Closed deerawan closed 3 years ago

deerawan commented 3 years ago

Hi GetStream team,

Please close this if it's not appropriate place to ask.

Tech stack

Issue

I'm building a service class in Angular as a wrapper for Stream. One of the functions is to get the messages from the active channel then convert it to our message schema using convertMessage function as seen below.

The convertMessage is also used to convert message when receiving a new message from websocket.

chat.service.ts

interface ChatMessage {
  first_name: string;
}

public getInitialMessages() {
  const messages = this._activeChannel.state.messages.map((message) => {
      const convertedMessage = this.convertMessage(message); // Typing error
      return convertedMessage;
    });
}

private convertMessage(message: MessageResponse): ChatMessage {
  return {
    // ... convert stream message obj to our custom message schema
   }; 
}

 private listenNewMessage(): void {
    this._activeChannel.on('message.new', (event) => {
      const newMessage = this._convertMessage(event.message);
      //.....
    });
  }

The error was

Argument of type 'ImmutableObject<Record<string, unknown> & { id: string; attachments?: (Record<string, unknown> & { actions?: Action[]; asset_url?: string; author_icon?: string; author_link?: string; author_name?: string; ... 12 more ...; type?: string; })[]; ... 7 more ...; user_id?: string; } & { ...; }>' is not assignable to parameter of type 'MessageResponse<Record<string, unknown>, Record<string, unknown>, LiteralStringForUnion, Record<string, unknown>, Record<string, unknown>, Record<string, unknown>>'.

The problem is the typing for state.messages is using Immutable which is not compatible with MessageResponse in the new message event. The Immutable typing seems to add more complexity there. What is the reason to make them different? Is there a way to convert Immutable to MessageResponse or vice versa?

What is the best way to handle this?

Thank you very much

mahboubii commented 3 years ago

hey @deerawan, Keep in mind that the message you get from message.new event is the exact message sent by API, however, the message we store in the channel.state is a bit different since we add some extra attributes and convert the timestamps to actual Date objects and convert it to immutable.

We are actually in the process of removing the Immutable wrappers but in the meantime, you can fix this either by using the channel.state.messageToImmutable() function on the event response or calling message.asMutable() on the message from the channel sate. If you still had issues with TS, try casting the message like message.asMutable() as MessageResponse

you can see the messageToImmutable here.

mahboubii commented 3 years ago

Please upgrade to v3 of the SDK which no longer uses ImmutableJS.