Let's suppose I have an interface
export interface INotification {
id: number;
DateReceived: number;
Title: string;
Message: string;
Tipology: string;
isRead: number;
}
and a reducer system. In my component I Could make and Observer
public notifications: Observable<INotification[]>;
constructor(private store: Store<AppState>) {
this.notifications = this.store.select<any>('notifications');
}
That's quite ok if my intent is just to show the elements in page like so..
<div *ngFor="let notification of notifications | async">
<div class="centralItem">
<p>
<b>{{notification.Title}}
</b>
</p>
<div [innerHtml]="notification.Message">
</div>
</div>
</div>
The Problem: I would like to observe all the Notifications inside my store that has the property isRead equals to 0 to count all those elements and put a badge like the image below:
Tryed many ways but i'm unable to map, filter, and i don't know what exactly i have to do to observe those items.. sorry i'm new with ngrx and all the observable pattern in JS - Typescript. Thanks.
EDIT: 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;
}
}
My AppState:
import { INotification } from '../models/notification.model';
export interface AppState {
readonly notification: INotification[];
}
My NgModule:
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: By now the best i can do is so:
public counter = 0;
ngOnInit() {
this.notifications.subscribe((notifs) => {
this.counter = 0;
notifs.forEach(elem => {
if (elem.isRead == 0)
this.counter++;
});
});
}
Looks like a little dirty but works XD
<ion-badge item-end *ngIf='counter > 0'>{{counter}}</ion-badge>
Add a subscription on the notificationsObservable like :
public hasNotifications: boolean;
ngOnInit() {
this.notifications.subscribe( notifs => {
this.hasNotifications = notifs.some( el => !el.isRead);
});
}
then use it like this on your element which should have a badge (basic html which can perhaps not reflect your case, but just to explain...) :
<div class="badge-holder">
<span *ngIf="hasNotification">MyBadge</span>
</div>