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

Issue with setting value using setState in TypeScript - what's the problem?

Every time I attempt to update the value of currentRole, it appears highlighted in red. Here is a screenshot for reference: const Container: React.FC<ContainerProps> = ({ children }) => { const [role, setRole] = useState<string>(); useE ...

Failed CORS request in Angular

I encountered an issue while attempting to connect to an external API (not owned by me), as I received a CORS error message (refer to screen 1). In an effort to resolve this, I added 'Access-Control-Allow-Origin': '*' to my headers, bu ...

What is the best way to retrieve a string from a URL?

Is there a way to extract only a specific string from a URL provided by an API? For instance: I'm interested in extracting only: photo_xxx-xxx-xxx.png Any suggestions on how to split the URL starting at photo and ending at png? ...

Form control identifier and input field name

I am currently developing a custom input feature for my application. One of the functionalities I want to include is auto-completion, and in my research, I found out that certain conditions need to be met for it to work: In order to enable auto-completi ...

An issue has been detected with the width attribute in Typescript when using

I have a question regarding the TypeScript error related to the width property. I've created a component called ProgressBar where I'm using Stitches for styling. However, TypeScript is throwing an error even when I specify the type as ANY. impor ...

Guide on verifying the snack bar's visibility and performing an action in e2e test using Protractor

Currently, I am conducting e2e testing using Protractor and encountering an issue with the snack bar feature. Here is a screenshot of the functioning app: Demo The dilemma lies in verifying the visibility of the snackbar on the page and how to execute the ...

Angular is used to send an HTTP GET request

I'm seeking assistance with implementing a get and put request in Angular. I understand how to initiate a get or put request when a button is clicked, by binding the request to the button itself. However, I am now looking for a way to trigger a get re ...

Angular - Implementing service worker to extract dynamic ID from route in "Notificationclick" event?

I have integrated push notifications into my code to notify users when an action is taken. The backend was developed using lib.net.webpush 3.1.0 with .net 4.5.2 in C#. The notification system is functioning well, but I am facing a challenge: Within my ser ...

Angular's ng-for directive allows for easy iteration over a collection of

I have a list of links that I am looping through using the ng-for directive. Each link is supposed to display an icon with different timing intervals thanks to a plugin called wowjs. The first link should appear quickly, while the last one should appear sl ...

How can I refresh the information in the navbar in Angular2?

Looking for guidance on the following scenario: I am working with two distinct components called navbar and homepage. The navbar has a specific area designated for displaying the city name. Within the homepage component, there is a form that includes a ...

Hello, I am looking for a way to maintain a user's active session when transitioning between different Angular applications without constantly prompting them to login. Can you help me

After logging in with my credentials, the session starts. However, if the user does not have an administrator role, I need to redirect them to another application. The challenge is maintaining the active session without requiring the user to log in again ...

Capable of retrieving response data, however, the label remains invisible in the dropdown menu

Upon selecting a country, I expect the corresponding city from the database to be automatically displayed in the dropdown menu. While I was able to retrieve the state response (as seen in the console output), it is not appearing in the dropdown menu. Inte ...

agm-info-window - Adjusting position to the right

Currently, I am using angular google maps to display maps along with markers and info windows. The issue I am facing is that the info window always appears on top. Is there a way to change its position to the right instead? <agm-map [latitude]="lat" ...

Issue: The parameter "data" is not recognized as a valid Document. The input does not match the requirements of a typical JavaScript object

I encountered the following issue: Error: Argument "data" is not a valid Document. Input is not a plain JavaScript object. while attempting to update a document using firebase admin SDK. Below is the TypeScript snippet: var myDoc = new MyDoc(); myDo ...

Leverage Angular, NodeJS, and Sequelize to extract data from HTML tables

Is there a way to extract data from a specific HTML table, identified by its ID, and save it into a mysql database using a NodeJS API with sequelize? The HTML code snippet that needs to be parsed: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 T ...

What could be causing my Ionic/Firebase subscription to be triggered three times?

I'm having an issue with my code where it seems to be executed 3 times and I can't figure out why. advertenciaMantto() { this.afs.doc('Core/Programador').valueChanges().subscribe(async (data) => { await this.afs.firestore.doc(` ...

Troubleshooting typescript error in styled-components related to Material-UI component

When using typescript and trying to style Material UI components with styled-components, encountering a type error with StyledComponent displaying Type '{ children: string; }' is missing the following properties import React, { PureComponent } f ...

Trigger a new Action upon successful completion of another action

I am a newcomer to the world of Angular and Redux. I have a common question for which I can't seem to find the right answer or maybe just need a helpful tip. I am utilizing ngrx in my application and I need to update some basic user data and then refr ...

Is it possible for Angular models to have relationships with one another? Can one model make references to

I have a complex navigation structure set up like this to create the top nav: [ {id: 1, label: 'Home', icon: 'fa-home', subitems: []}, {id: 2, label: 'Sitemap', icon: 'fa-sitemap', subitems: []}, ...

The Issue with NG-Zorro Datepicker Manual Input Mask Functionality未分类

Is there a way to mask the datepicker so that users can enter dates in the format MM/dd/yyyy without typing the "/" character manually? I've tried using ngx-mask but it doesn't seem to work for the datepicker component. I have provided a link to ...