If we consider an interface called INotification:
export interface INotification {
id: number;
DateReceived: number;
Title: string;
Message: string;
Tipology: string;
isRead: number;
}
and a reducer system. In the component, it's possible to create an Observer like this:
public notifications: Observable<INotification[]>;
constructor(private store: Store<AppState>) {
this.notifications = this.store.select<any>('notifications');
}
This setup works well for displaying the elements on the page as shown below:
<div *ngFor="let notification of notifications | async">
<div class="centralItem">
<p>
<b>{{notification.Title}}
</b>
</p>
<div [innerHtml]="notification.Message">
</div>
</div>
</div>
The Challenge: The goal is to observe all the Notifications in the store that have the property isRead set to 0, count these elements, and then display a badge. For reference, here is how the badge should look: https://i.stack.imgur.com/TlsFf.jpg
I've tried various approaches but struggling with mapping, filtering, and understanding the necessary steps to observe those specific items. I'm relatively new to ngrx and the observable pattern in JS - Typescript. Any guidance would be appreciated.
For context, here is my Reducer:
import { Action } from '@ngrx/store'
import { INotification } from './../models/notification.model'
import * as NotificationActions from './../actions/notification.actions'
export function reducer(state: INotification[] = [], action: NotificationActions.Actions) {
console.log(action);
switch (action.type) {
case NotificationActions.ADD_NOTIFICATION:
return [...state, action.payload].sort(compare);
case NotificationActions.REMOVE_NOTIFICATION:
state.splice(action.payload, 1).sort(compare);
return state;
case NotificationActions.REMOVE_NOTIFICATIONS_BY_TIPOLOGY:
return state.map(val => val.Tipology != action.payload).sort(compare);
default:
return state.sort(compare);
}
function compare(a, b) {
const aDate = a.DateReceived;
const bDate = b.DateReceived;
let comparison = 0;
if (aDate > bDate) {
comparison = -1;
} else if (aDate < bDate) {
comparison = 1;
}
return comparison;
}
}
And here is my AppState:
import { INotification } from '../models/notification.model';
export interface AppState {
readonly notification: INotification[];
}
Finally, here is My NgModule configuration:
NgModule({
declarations: [
MyApp,
AuthLoader
],
imports: [
BrowserModule,
HttpModule,
IonicModule.forRoot(MyApp),
StoreModule.forRoot({ notifications: reducer })
],
bootstrap: [IonicApp],
entryComponents: [
MyApp,
AuthLoader
],
providers: [
StatusBar,
SplashScreen,
{ provide: ErrorHandler, useClass: IonicErrorHandler }
]
})
SOLVED: The current solution involves tracking the number of unread notifications using this method:
public counter = 0;
ngOnInit() {
this.notifications.subscribe((notifs) => {
this.counter = 0;
notifs.forEach(elem => {
if (elem.isRead == 0)
this.counter++;
});
});
}
Although it may seem messy, it gets the job done XD
<ion-badge item-end *ngIf='counter > 0'>{{counter}}</ion-badge>