Creating a dynamic array in an Angular 2 service for real-time changes monitoring by a component

I am facing an issue where my NotificationsBellComponent is not receiving changes to the array in the service even though the _LocalStorageService is returning data correctly.

Q) How can I ensure that my component receives updates when the service collection changes?

Current implementation of the component:

@Component({
    selector: 'notifications-bell',
    directives: [],
    templateUrl: 'build/components/notificationsBell/notificationsBell.html',
    styles: [`
        button{
            background: none !important;
            background-color: none !important;
            box-shadow: none !important;
        }
    `]
})
export class NotificationsBellComponent {

    private notifications: string[];

    constructor(
        private _platform: Platform,
        private _nav: NavController,
        private _events: Events,
        private _ConfigService: ConfigurationService,
        private _NotificationService: NotificationService
    ) {
        this.notifications = this._NotificationService.notifications;
    }
}

Current implementation of the service:

@Injectable()
export class NotificationService {

  public notifications: string[];

  constructor(
    private _ConfigService: ConfigurationService,
    private _LocalStorageService: LocalStorageService,
    private _I8nService: I8nService,
    private _events: Events
  ) {
    this.getData();
  }

  getData() {
    this._LocalStorageService.getNotifications().then((data) => {
      var list: string[] = [];
      if (data.res.rows.length > 0) {
        for (var i = 0; i < data.res.rows.length; i++) {
          list.push(data.res.rows.item(i).notification);
        }
      }
      this.notifications = list;
    });
  }

  addItem(description: string) {
    this._LocalStorageService.addNotification(description).then(() => {
      this.getData();
    });
  }
}

Answer №1

retrieveData() assigns alerts to a fresh array every time the promise is fulfilled. Your component will retain a connection to the original array.

Instead of creating a new array repeatedly, simply clear it and use push() to add new data:

export class NotificationService {
  public notifications: string[];
  getData() {
    this._LocalStorageService.getNotifications().then((data) => {
      this.notifications.length = 0; // empty the array while maintaining its reference
      if (data.res.rows.length > 0) {
        for (var i = 0; i < data.res.rows.length; i++) {
          this.notifications.push(data.res.rows.item(i).notification);
        }
      }
    });
  }
  ...
}

Answer №2

Instead of creating an array within the service,

You should keep the observable sequence intact: If you need an observable in your component, make sure to maintain it as a stream all the way through without splitting it up in the service.

Consider structuring your code like this:

@Injectable()
export class NotificationService {

  public notifications$: Observable<string[]>;

   constructor(
     private _ConfigService: ConfigurationService,
     private _LocalStorageService: LocalStorageService,
     private _I8nService: I8nService,
     private _events: Events
   ) {
      this.notifications$ = this._LocalStorageService.getNotifications()
          .map(notifications => {
              // adjust notifications as needed
          }) 

   }
}

Then, subscribe to service.notifications$ in your component.

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

The placeholder within my input moves up and down when switching the input type from password to text

Currently, I am encountering an issue with the styling of a standard input element in React. Specifically, the placeholder text moves up and down by about 2px when viewed on Chrome, while there are no problems on Safari. How can I go about resolving this i ...

`How can I enhance the appearance of an Angular 4 component using an attribute?`

There is a component where I need to pass specific data to the child components within an ngFor loop using attributes. Depending on the attribute, I want to style these child components accordingly. Code testimonials.component.html - (Parent component) ...

What is the correct method for retrieving a specific child element in React?

In my React project, I have created a component that consists of various subcomponents: import React, { FunctionComponent } from 'react'; import { FormControl, FormGroup, FormGroupProps, FormLabel, FormText, FormTextProps } from 'react-boots ...

What is the best way to retrieve the output value using the EventEmitter module?

I have an element that sends out a simple string when it is clicked Here is the HTML code for my element: <div (click)="emitSomething($event)"></div> This is the TypeScript code for my element: @Output() someString: EventEmitter<string& ...

The karma test encounters difficulties in establishing a connection with the 'chrome' instance that has been launched

Currently, I am facing an issue with my Karma test running on a nodejs jenkins pod. npm is timing out when trying to connect to the Chrome instance on the selenium hub. Everything was working fine until yesterday without any changes made to the configura ...

Angular14 offers a unique highcharts speedometer with multiple dials in the gauge chart for a visually stunning

Looking to create a unique speedometer design with an inner dial and an additional triangular indicator using Highcharts gauge within the Angular14 framework. Is it possible to include an extra indicator with Highcharts gauge in Angular14? Click on the l ...

The data table fails to display updated information from the data source

After updating the data-array (FileDto), I am unable to see any changes reflected in the Datatable. I have tested outputting the data using ngFor, and it works perfectly fine. Here is the HTML code: <ngx-datatable class="material striped" [rows]= ...

The InAppPurchase Plugin in Cordova is throwing the error message "Encountered an error: Cannot access the 'getProducts' property as it is undefined."

Currently, I am utilizing the cordova in-app-purchase plugin for my application. However, I am encountering an error that reads "ERROR TypeError: Cannot read property 'getProducts' of undefined" The .ts file appears as follows: window['plu ...

Encountering a problem when attempting to utilize AngularFire's Cloud Messaging Angular module due to missing configuration values for the app

Working with Firebase Cloud Messaging in my Angular application using AngularFire2 has presented a challenge. I am facing an error when attempting to retrieve the user's current token. I have already set up the "firebase-messaging-sw.js" and "manifes ...

Testing in Vue revealed an unexpected absence of data

I am facing difficulties when it comes to creating tests. Currently, I have a view that is supposed to verify an email address using an authentication code. At the moment, the view exists but no connection is established with an email service or code gener ...

Error encountered with npm version 5.8.0 while trying to create a new project using ng new

I keep encountering this error whenever I try to create a new Angular project. I'm unsure whether it is an npm or angular-cli issue. node -v v8.11.1 npm -v 5.8.0 ng -v 6.0.0 Everything seemed fine before this occurred. Even serving other projects ...

A guide to integrating a component into another component in Angular

Currently, I am encountering an issue with importing a component into another in my Ionic 5.0.0 application. Within my application, I have two separate modules: ChatPageModule and HomePageModule. My objective is to include the Chat template within the Hom ...

Personalized data based on the language within Next.js

Is there a way to customize Metadata for users based on search engine keywords? To enhance SEO performance on my website, I am working on setting up unique Metadata for the two languages my website supports: English and Portuguese. Specifically, I aim to ...

Troubleshooting Issue with Chrome/chromium/Selenium Integration

Encountered an issue while attempting to build and start the application using "yarn start": ERROR:process_singleton_win.cc(465) Lock file cannot be created! Error code: 3 Discovered this error while working on a cloned electron project on a Windows x64 m ...

Ionic datetime returns default values upon initialization

I'm currently in the process of developing an Ionic-Angular-app. I require a datetime component on a page to set the creation date of an object. I am using formGroup for this purpose, but whenever I choose a different date, it always reverts back to t ...

Creating dynamic keys to insert objects

In my coding project, I am dealing with an empty array, a value, and an object. Since there are multiple objects involved, I want to organize them into categories. Here is an example of what I envision: ARRAY KEY OBJECT OBJECT KEY OBJECT ...

How to Share Angular Modules Between Two Projects with Ivy Compilation Necessity

Query: I am faced with the challenge of sharing common modules between two Angular projects, one of which requires full Ivy compilation to function properly. To manage these shared resources, we have set up a private GitHub NPM repository. However, becaus ...

Attempting to invoke a promise within a function yields an error message stating that it lacks call signatures

Recently, I came across this interesting class: export class ExponentialBackoffUtils { public static retry(promise: Promise<any>, maxRetries: number, onRetry?: Function) { function waitFor(milliseconds: number) { return new Pr ...

Leverage the generic parameter type inferred from one function to dynamically type other functions

I am in the process of developing an API for displaying a schema graph. Here is a simplified version of what it entails: interface Node { name: string; } type NodeNames<T extends Node[]> = T[number]["name"]; // Union of all node names as strings ...

Troubleshooting problem with Angular HttpClient when invoking Bing Maps Locations REST APIs

Currently, I have successfully implemented a Bing Maps call using Angular 4 Http service: this.http.get("{absolute URL of Bing Maps REST Locations, with options and key}") Now, I am trying to transition this call to use the newer HttpClient service in An ...