4

I'm trying to create a simple selector to get all the messages in the store by a visitor_id, however, what seems so simple to do is always challenging to achieve in ngrx.

I'm using ngrx entity, so I already have the selectAll selector ready, so i tried to do the following:

export const selectMessagesState = createFeatureSelector<MessagesState>('messages');

export const selectAllMessages =  createSelector(
    selectMessagesState,
    fromMessage.selectAll
);

export const selectMessageByVisitorId = createSelector(
    select(selectAll),
    (visitor_id) => map(val => val.filter(c => c.visitor_id == visitor_id))
);

and in the components:

export class Message {
    id: number;
    message: string;
    visitor_id: number;
    is_from_visitor: boolean;
    created_at: string;
}
public messages$ : Observable<Message[]>;

public showThread(visitor: Visitor){

   this.messages$ = this.store.select(selectMessageByVisitorId({ visitor_id: visitor.id}));

However i'm getting Property 'filter' does not exist on type 'unknown' in selectMessageByVisitorId. I'm pretty sure i'm not following the right approach. What I'm trying to do is simple, pass a visitor id to the selectMessageByVisitorId selectir, where it returns the list of messages in the feature store, filtered by the visitor_id.

Update #1

As per @Nikhil suggestion, I changed the selector to :

export const selectMessageByVisitorId = ({visitor_id}) => createSelector(
    select(selectAll),
    messages => messages.filter(val => val.visitor_id == visitor_id)
);

However I'm getting Property 'filter' does not exist on type 'Observable<Message[]>, event though i imported import { filter} from 'rxjs/operators'; (im using ngrx 8.0).

So I though of trying:

export const selectMessageByVisitorId = ({visitor_id}) => createSelector(
    select(selectAll),
    messages => messages.pipe(
            map(val => val.filter(c => c.visitor_id == visitor_id)  ) 
        )
);

but now im getting Type 'Observable<Observable<Message[]>>' is not assignable to type 'Observable<Message[]>'. in the component file this.messages$ = this.store.select(selectMessageByVisitorId({ visitor_id: visitor.id}));

nash11
  • 8,220
  • 3
  • 19
  • 55
Yehia A.Salam
  • 1,987
  • 7
  • 44
  • 93

1 Answers1

3

map() isn't needed here, just use filter().

Approach 1:

export const selectMessageByVisitorId = ({visitor_id}) => createSelector(   
    pipe(
     select(selectAll),
     filter(val => val.visitor_id == visitor_id)
    )
);

Approach 2:

export const selectAllMessages =  createSelector(
    selectMessagesState,
    fromMessage.selectAll
);

export const selectMessageByVisitorId = ({visitor_id}) => createSelector(
    selectAllMessages,
    messages => messages.filter(val => val.visitor_id == visitor_id)
);

Then subscribe to the messages.

this.messages$ = this.store.select(
  selectMessageByVisitorId({visitor_id: visitor.id})
);

this.messages$.subscribe((messages) => {
  // Handle response.
  console.log(messages);
});
Nikhil
  • 6,493
  • 10
  • 31
  • 68
  • didnt compile unfortunately, getting `Property 'visitor_id' does not exist on type 'unknown'` on the filter function, also `(visitor_id)` is shown as of type `Observable – Yehia A.Salam Sep 28 '19 at 22:44
  • Based on your `RxJS` version, make sure you import proper module. Check out this [answer](https://stackoverflow.com/a/39514938/2924577). – Nikhil Sep 28 '19 at 22:51
  • filter was imported, however the problem is in the input `val` to the filter function is assumed to be unknown – Yehia A.Salam Sep 29 '19 at 11:58
  • @YehiaA.Salam - Check out my edited answer and let me know if you have any issues. – Nikhil Sep 29 '19 at 17:03
  • thanks a lot of helping out, i updated the question, close, but not there yet – Yehia A.Salam Sep 29 '19 at 19:20
  • @YehiaA.Salam - I edited my answer with two approaches. Can you try both of them and see if they are working? – Nikhil Sep 29 '19 at 19:30
  • I tried the second approach, but when assigning the observable to the selector in `this.messages$ = this.store.select(selectMessageByVisitorId({ visitor_id: visitor.id}));`, nothing happens and the breakpoints in `createSelector` are not being fired at all – Yehia A.Salam Oct 01 '19 at 19:03
  • @YehiaA.Salam - Make sure you subscribe to the messages as shown in my answer. – Nikhil Oct 02 '19 at 00:23