Utilize Ngrx to keep an eye on specific items within the store

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>

Answer №1

To set up a subscription for notifications, add the following code to your notificationsObservable:

public hasNotifications: boolean;
ngOnInit() {
   this.notifications.subscribe( notifs => {
      this.hasNotifications = notifs.some( el => !el.isRead);
   });
}

Then, you can use it in your HTML element that should display a badge like this (the HTML provided is basic and may need to be adjusted for your specific case):

<div class="badge-holder">
  <span *ngIf="hasNotification">MyBadge</span>
</div>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

List out the decorators

One query is bothering me - I am attempting to create my own version of Injectable and I need to determine if a specific decorator exists in my Class. Is there a way to list all decorators of a class? Let's take the example below. All I want to know i ...

Allowing HTML attributes in reusable components with Vue TSX: A guide on informing Typescript

Imagine I have a custom input component: import { defineComponent } from "@vue/runtime-core" export default defineComponent({ inheritAttrs: false, setup(props, { attrs }) { return () => ( <div> ...

"Angular 4 is requesting a required get parameter that is currently missing

After running my code, I encountered the following console log error: "'Missing required 'page' parameter". I attempted to set this as a parameter in my get request, and it seemed successful because I was able to view the params as an array ...

What is the best way to populate empty dates within an array of objects using TypeScript or JavaScript?

I am trying to populate this object with dates from today until the next 7 days. Below is my initial object: let obj = { "sessions": [{ "date": "15-05-2021" }, { "date": "16-05-2021" }, { "date": "18-05-2021" }] } The desired ...

What are the steps for incorporating a Zoom & Pan feature into an anyChart SeatMap?

In our IONIC application, we are utilizing the anyChart SeatMap to display SVG-based seatmaps. However, some of the seatmaps are quite large and we require support for zooming and panning functionalities. Despite researching the 'Move & Zoom' opt ...

Setting a maximum value for a text box input in Angular for enhanced bot functionality

Currently, I am working with Angular 7 and I find myself trying to incorporate the min and max properties into a textbox. However, I seem to be encountering some difficulties in achieving this. <div> <input type='text' [(ngModel)]= ...

Steps for displaying detailed information about a single product on an Ecommerce page

Currently in the process of developing my Ecommerce project, I have successfully created a product grid with links to each specific product. However, I am facing an issue where I am unable to view the data of each individual item. Below is the code for my ...

Validating React Typescript Props: Ensuring that two specific props do not exist simultaneously

Currently, I'm developing a reusable component in React-Typescript and I am looking to validate my props OnClick and component as follows: Both onClick and component prop are optional. These props will only be passed to the component if they need to ...

Saving documents in a PostgreSQL database with the help of NodeJS and Angular2+

I have researched various tutorials and examples on the internet for uploading and storing files in PostgreSQL using NodeJS, Multer, Sequelize, Express, but haven't found a solution that works for my project. My project consists of an Angular app wit ...

Importing TypeScript modules dynamically can be achieved without the need for Promises

I find myself in a scenario where the dynamic nature of these commands is crucial to prevent excessive loading of unnecessary code when executing specific command-line tasks. if (diagnostics) { require('./lib/cli-commands/run-diagnostics').run ...

How to redefine TypeScript module export definitions

I recently installed a plugin that comes with type definitions. declare module 'autobind-decorator' { const autobind: ClassDecorator & MethodDecorator; export default autobind; } However, I realized that the type definition was incorrec ...

Exploring Angular: The Dynamic Declaration of object.property in ngModel

<input [(ngModel)]="Emp."+"dt.Rows[0]["columnname"]"> This scenario results in an undefined value In my current project, I am leveraging the power of a MVC CustomHtmlHelper to generate textboxes dynamically based on database schema. The textbox ...

Is there a way to install @types that are compatible with an outdated version of TypeScript?

I am currently working on a project that relies on packages such as @types/express and @types/body-parser. The problem is, the recent updates to these .d.ts files have introduced generic defaults, which now require TypeScript 2.3 or higher. Unfortunately, ...

Discovering the root cause of performance issues in a v14 Angular application

I am currently working on a web application built with Angular 14. During my testing with Lighthouse, I have discovered that the performance of the application is satisfactory on desktop but falls short for mobile users. The application consists of three ...

Angular TypeScript state management system

I am facing a challenge in connecting a controller to a state (using angular ui.router) where one way of writing it works, while the other does not. Successful example (with the controller registered under the module): this.$stateProvider .state(' ...

Checkbox selections persist when navigating between pages

I am currently working with Angular 9 and I have a list of checkboxes that need to default to true when displaying certain data. If one of these checkboxes is unchecked, it should trigger the display of specific information. The issue I am facing is that o ...

In TypeScript, what specific type or class does a dynamically imported module belong to?

Can someone assist me in determining the type of an imported module in TypeScript? Here is my query: I have a module called module.ts export class RSL1 {}; Next, I import it into my index.ts using the following code: const script = await import('mod ...

Having trouble locating the angular-devkit while trying to update Angular

I encountered the following error message: An unhandled exception occurred: Cannot find module '@angular/compiler-cli' See "C:\Users\rashe\AppData\Local\Temp\ng-s9ZG05\angular-errors.log" for further details. ...

Using Angular styleUrls directory over individual files

https://i.stack.imgur.com/vg7Ot.png Is there a way to dynamically include all stylesheets from a specific directory instead of hardcoding each URL in styleUrls in Angular? For example, something like: referencing all stylesheets from the './styles/&a ...

Exploring the process of iterating over asynchronous data in Angular

There is an angular component in my project that fetches data from the server, processes it, and then assigns it to a variable: class Component { data = []; ngOnInit() { this.store.select(data).pipe( map(data => { this.data = this.transf ...