BehaviorSubject Observable continuously notifies unsubscribed Subscription

Utilizing a service called "settings", initial persisted values are read and provided through an observable named "settings$" to components that subscribe to it. Many components rely on this observable to retrieve the initial values and exchange updated values among themselves using BehaviorSubject implemented in the service.

@Injectable()
export class SettingsService implements OnInit {

  settingsBS; 
  settings$: Observable<SettingsI>;

  init() {
    this.settingsBS = new BehaviorSubject<SettingsI>(defaultSettings);
    this.settings$ = this.settingsBS.asObservable();
    ...
    let s: SettingsI;
    this.loadPersistedSettings(s);
                       // notify subscribers about the 
                       // loaded persisted settings 
                       // and pass these settings to them
    this.notifySubscribers(s);
    ...
  }
                      // this function is also used by components
                      // to pass new/updated settings to subscribers
  public notifySubscribers(s: SettingsI) {
    this.settingsBS.next(s);
  }
  ...
}

While most functionality works as expected, one particular component requires access to the initial persisted data but does not wish to receive further updates for "settings". Thus, the component subscribes initially to obtain the data and then unsubscribes to prevent any future updates as demonstrated below.

constructor(private settingsService: SettingsService, ...) { ... }

ngOnInit() {
  const settingsSubscription = this.settingsService.settings$.subscribe(o => 
  {
      merge(this.persistedSettings, o);
      ...
  });
  ...
  settingsSubscription.unsubscribe;
}

Despite calling "settingsSubscription.unsubscribe;", the subscription persists and the section inside the subscription continues to trigger whenever the service function:

settingsService.notifySubscribers(s)

This raises two questions:

  1. Why does "settingsSubscription.unsubscribe;" fail to cancel the subscription?

  2. How can this issue be resolved?

Answer №1

Unsubscribing is a method and not a property, so you must use (). This will look like:

.unsubscribe();

If your objective is to subscribe and receive only the initial persisted data, you can use: take(1)

this.settingsService.settings$.pipe(take(1)).subscribe(...)

This method will automatically unsubscribe after receiving the initial data.

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

What is the best way to calculate the variance between the most recent and previous data points in an array in the span of an hour using JavaScript

Here is an array of objects I am working with: 0: {time: '2021-12-02T23:53:54.062Z', value: 558316} 1: {time: '2021-12-03T00:53:53.959Z', value: 558452} 2: {time: '2021-12-03T01:53:53.934Z', value: 558588} 3: {time: '2021 ...

Make simultaneous edits to multiple cells in IGX GRID for Angular

Is it feasible to edit multiple cells in the same column simultaneously within igx grid Angular? I would like for the changes made within each cell to be displayed at the same time. Editing many cells all at once is a valuable feature! ...

Exploring the wonders of delayed execution through rxjs

I am looking for a way to incorporate delayed execution into my application. Specifically, I want to prevent server requests from being sent while the user is still typing in a search string. This functionality is commonly seen in search engines like Goo ...

Converting JSON responses from Observables to Arrays of objects in Angular

I have created a custom interface called Table which defines the structure of my data. export interface Table { id: number; title: string; status: string; level: string; description: string; } In my service, I am using HttpClient to se ...

Updates to Providers in the latest release of Angular 2

When working with angular 2.0.0-rc.1, we implemented a Provider using the new Provider method as shown in the code snippet below: var constAccessor = new Provider(NG_VALUE_ACCESSOR, { useExisting: forwardRef(() => EJDefaultValueAccessor), ...

What is the reason behind TypeScript choosing to define properties on the prototype rather than the object itself?

In TypeScript, I have a data object with a property defined like this: get name() { return this._hiddenName; } set name(value) { ...stuff... this._hiddenName = value; } However, when I look at the output code, I notice that the property is on ...

In what way does Ionic determine the URL for input and send the password-protected email for logging in based on that URL?

I've set up a section for inserting the URL into the login form page using the following code: <ion-item> <ion-label floating>Company URL</ion-label> <ion-input type="url" value="" required></ion-input> </ion-item> ...

Exploring the power of Vue3 with reactive nested objects and the inclusion of

It seems like I've encountered a bit of a challenge... Perhaps a bug in Vue3 with Typescript and the composition API, or maybe I'm missing something. I'm facing an issue where I'm not getting any intellisense in my IDE (Webstorm) when ...

Stuck on loading screen with Angular 2 Testing App

Currently working on creating a test app for Angular 2, but encountering an issue where my application is continuously stuck on the "Loading..." screen. Below are the various files involved: app.component.ts: import {Component} from '@angular/core& ...

Sending text containing HTML elements from the parent component to the child component

I'm facing a challenge where I need to transfer a string from my parent component to my child component. The string includes HTML tags with an HTML entity. Here's how it looks in the parent template: <child-component i18n-componentContent=&quo ...

Connecting attribute in Angular 5 through @Input

(UPDATED) I originally had a basic jarallax setup with just a div containing the corresponding configuration in a component: <div class="view cover-jarallax" data-jarallax="{"speed": '0.w'}" style="background-image: url(imgurl);' + &apo ...

Angular HTTP requests are failing to function properly, although they are successful when made through Postman

I am attempting to send an HTTP GET request using the specified URL: private materialsAPI='https://localhost:5001/api/material'; setPrice(id: any, price: any): Observable<any> { const url = `${this.materialsURL}/${id}/price/${price}`; ...

Invoking a method in a derived class upon completion of asynchronous logic within the base class

Currently, I am in the process of building an Angular application. One aspect of my project involves a class that extends a base class. While this approach may not be ideal, I am curious to know what would be the best practice for BaseClass to trigger me ...

The attribute is not found on the combined type

After combing through various questions on stackoverflow, I couldn't find a solution to my specific case. This is the scenario: interface FruitBox { name: string desc: { 'orange': number; 'banana': number; } } interf ...

Having trouble with the lodash find function in my Angular application

npm install lodash npm install @types/lodash ng serve import { find, upperCase } from 'lodash'; console.log(upperCase('test')); // 'TEST' console.log(find(items, ['id', id])) // TypeError: "Object(...)(...) is un ...

Avoiding hydration errors when using localStorage with Next.js

Want to save a token and access it using local storage The code snippet I am using is: if (typeof window !== 'undefined') { localStorage.setItem(key, value) } If I remove the window type check, I encounter this error: localStorage is not ...

Delete the text in MUI's TablePagination component that displays the number of rows per page and the total rows in the table

Currently, I am integrating MUI's tablePagination component into my React table with TypeScript. I am looking to remove/disable the circlemarked text displayed in the image (the picture is an example from MUI). https://i.stack.imgur.com/ib0t2.png Af ...

Find the appropriate return type for a TypeScript function based on its argument

Is it feasible in TypeScript to infer the return type of a function based on its arguments? This feature would be beneficial when extracting specific properties from, for example, a database query. Here is an illustration () : type QueryReturnType = { a ...

Type inference error in TypeScript occurs within a conditional statement when the condition relies on the output of a function call rather than a boolean expression

In my TypeScript code, I have a Linked List class that is working perfectly. The class includes a Node type and functions to add items to the list. type ListItem = number | string | object; class Node { private value: ListItem; private next: Node | nu ...

Guide on resolving the error "Type 'Emits' does not have any call signatures" in Vue 3 with the combination of script setup and TypeScript

I've come across some code that seems to be functioning properly, but my IDE is flagging it with the following warnings: TS2349: This expression is not callable. Type 'Emits' has no call signatures Below is the code snippet in question: ...