How Applay Filter to Observable and get the length of list to count notification for each user

Viewed 62

How Applay Filter to Observable and get the length of list to count notification for each user: how can I get the count of notification type number for each user by html code

<div class="users-list-body">
  <div>
    <h5>
      {{ onlineusermodel.userName }}
    </h5>
    <p>It seems logical that the</p>
  </div>
  <div class="last-chat-time">
    <small class="text-muted">05 min</small>
    <div class="new-message-count">
      {{ getUserNotification(onlineusermodel) }}
    </div>
  </div>
</div>

component ts

getUserNotification(onlineUserModel: OnlineUserModel): Number {
 // var count = this.allNotifications$.subscribe((n) =>
 //   n.filter((u) => u.onlineUserModel == onlineUserModel).length
 // );
 var count = this.store
   .pipe(select(selectDirectNotifications))
   .subscribe(
     (n) => n.filter((u) => u.onlineUserModel == onlineUserModel).length
   );

 return count;
}

Reducer

const directMessagesReducerInternal = createReducer(
 initialState,
 on(
   directMessagesAction.receivedNotificationForUserAction,
   (state, { payload }) => {
     const directNotification: DirectNotification = {
       onlineUserModel: payload.onlineUserModel,
       notificationModel: payload.notificationModel,
     };
     return {
       ...state,
       allNotifications: [...state.allNotifications, directNotification],
     };
   }
 ),

state

allNotifications: DirectNotification[];

selector

export const selectDirectNotifications = createSelector(
 selectDirectMessageStore,
 (state: DirectMessagesState) => state.allNotifications
);

Action

export const receivedNotificationForUserAction = createAction(
 "[DN] RECEIVED_DIRECT_NOTIFICATION",
 props<{ payload: ReceivedNotificationForUserDto }>()
);
1 Answers

Not Recommended Way: You can achieve that by returning the Observable instead of subscribing to it from getUserNotification, then subscribe to it in the template using the async pipe, like the following:

getUserNotification(onlineUserModel: OnlineUserModel): Observable<number> {
  return this.store.pipe(
    select(selectDirectNotifications),
    map((n) => n.filter((u) => u.onlineUserModel == onlineUserModel).length)
  );
}
<div class="users-list-body">
  <div>
    <h5>
      {{ onlineusermodel.userName }}
    </h5>
    <p>It seems logical that the</p>
  </div>
  <div class="last-chat-time">
    <small class="text-muted">05 min</small>
    <div class="new-message-count">
      {{ getUserNotification(onlineusermodel) | async }}
    </div>
  </div>
</div>

However, it's not recommended to use the functions directly in the component template (HTML file), because Angular will call it on each change detection, which is not preferred from the performance point of view.

Instead, the recommended way is to assign the value of getUserNotification to an Observable once the data is ready and then subscribe to that Observable in the component template, like the following:

ngOnInit(): void {
  // ngOnInit is used here as an example.
  // You can assing the result of `getUserNotification` function each time the `onlineUserModel` has been changed:
  this.userNotificationCount$ = this.getUserNotification(onlineUserModel);
}

getUserNotification(onlineUserModel: OnlineUserModel): Observable<number> {
  return this.store.pipe(
    select(selectDirectNotifications),
    map((n) => n.filter((u) => u.onlineUserModel == onlineUserModel).length)
  );
}
<div class="users-list-body">
  <div>
    <h5>
      {{ onlineusermodel.userName }}
    </h5>
    <p>It seems logical that the</p>
  </div>
  <div class="last-chat-time">
    <small class="text-muted">05 min</small>
    <div class="new-message-count">
      {{ userNotificationCount | async }}
    </div>
  </div>
</div>
Related