Kevin Malone
Kevin Malone

Reputation: 65

How to use filter with switchMap?

I have an observable that should watch every Chat Message that has a type 'private'

So what I'm trying to do is to use the function filter() from rxjs to watch every Chat Message that has a type private so I can use it in my variable chatMessagePrivate$

Here is what I tried:

export type ChatType = 'private' | 'standard';

export class ChatMessage {
  uid?: string;
  chatRoomUid: string;
  type: ChatType;
}

chatMessagePrivate$: Observable<ChatMessage[]>;

ngOnInit() {
  this.chatMessagePrivate$ = this.chatRoom$.pipe(
    switchMap((chatRoom: ChatRoom) => this.chatMessageService.getAllByChatRoomUid$(chatRoom.uid) // this function returns every message from the uid of the chatroom
      .filter(chatRoom => 'private')
      )
    );
}

And I'm getting the following error: Type 'string' is not assignable to type 'boolean'

How can I use filter() to get all ChatMessage with the type 'private' ?

Upvotes: 3

Views: 7293

Answers (3)

SparkFountain
SparkFountain

Reputation: 2270

In case you should use redux actions, you could use the special ofType filter from RxJS to retrieve exactly all actions whose chat type equals "private".

this.chatMessagePrivate$ = this.chatRoom$.pipe(
    ofType('private'),
    switchMap((chatRoom: ChatRoom) => this.chatMessageService.getAllByChatRoomUid$(chatRoom.uid) // this function returns every message from the uid of the chatroom
      )
    );

Otherwise, without redux and in case this.chatRoom$ already contains the information whether the chat room is private or not, I would suggest you attach the filter before the actual service method call:

this.chatMessagePrivate$ = this.chatRoom$.pipe(
    filter(chatRoom:  => chatRoom.type === 'private'),  // in case the "type" property exists
    switchMap((chatRoom: ChatRoom) => this.chatMessageService.getAllByChatRoomUid$(chatRoom.uid)
    );

Upvotes: 2

Harun Yilmaz
Harun Yilmaz

Reputation: 8558

filter of RxJS v6+ (I assume you use v6+) is a pipeable operator. So you need to use it like:

this.chatMessageService.getAllByChatRoomUid$(chatRoom.uid).pipe(
   filter(cr => cr.type === 'private')
);

For further reading: https://www.learnrxjs.io/operators/filtering/filter.html


UPDATE:

Since the response is an array, you need to use Array.filter. You can do it like following:

this.chatMessageService.getAllByChatRoomUid$(chatRoom.uid).pipe(
   map(crArr => crArr.filter(cr => cr.type === 'private'))
);

Upvotes: 5

Mustahsan
Mustahsan

Reputation: 3862

.filter() expects a boolean so try this:

.filter(chatRoom => chatRoom.type === 'private')

IF this this.chatMessageService.getAllByChatRoomUid$(chatRoom.uid) returns an Observable then you might have to use pipe:

this.chatMessagePrivate$ = this.chatRoom$.pipe(
switchMap((chatRoom: ChatRoom) => this.chatMessageService.getAllByChatRoomUid$(chatRoom.uid)) // this function returns every message from the uid of the chatroom
  ,filter(chatRoom => chatRoom.type === 'private')
  )
);

Upvotes: 2

Related Questions