The subscription functionality within the extended class constructor is not functioning as intended

An abstract class named CoreButtonService has been created, which will serve as the base for other ButtonServices like UserButtonService and MessageButtonService. These services will be injected into corresponding components such as UserComponent and MessageComponent. In the constructor of CoreButtonService, a subscription to ButtonsService has been implemented to handle events triggered when buttons in the ButtonModule are clicked.

CoreButtonService:

export abstract class CoreButtonService<T extends CoreModel> extends CoreService {

    private backSource = new Subject<string>();
    private submitSource = new Subject<string>();
    back$ = this.backSource.asObservable();
    submit$ = this.submitSource.asObservable();

    constructor(
        private coreButtonsService: ButtonsService,
        private coreLanguageService: LanguageService,
        private coreLocation: Location) {
        super(coreLanguageService);
        this.coreButtonsService
            .buttonClicked$
            .subscribe(button => console.log(button)); // !!!!!!
    }

    // Additional button functionality goes here ...

}

ButtonsService:

@Injectable()
export class ButtonsService {
    private button = new Subject<ButtonBase<any>>();
    buttonClicked$ = this.button.asObservable();
    constructor(private formService: FormService) { }

    clickButton(button: ButtonBase<any>): void {
        if (button.controlType === 'submit')
            this.formService.submitForm(button.parent);
        this.button.next(button);
    }
}

When visiting a page with UserComponent and MessageComponent, clicking buttons should result in 2 logged buttons on the console - one for each component identifiable by button.parent. However, only buttons from MessageComponent are being displayed instead of both. Upon saving the sent parent in CoreButtonService and logging it along with the button, correct values ('MessageForm' and 'UserForm') are obtained. Surprisingly, the values of button.parent are identical. How can this discrepancy be explained?

The issue could potentially be due to every ButtonService subscribing within CoreButtonService, causing interrelated subscriptions and buttons.

UPDATE

For further reference, you can view the plunkr demonstrating the basic concept.

Answer №1

After thorough investigation, I have identified the error and it turned out to be quite trivial. In the CoreComponent, I mistakenly unsubscribed using:

ngOnDestroy() {
    this.subscription.unsubscribe();
}

This led to some unexpected behavior with the events. Nonetheless, I appreciate the assistance provided. Thank you.

Answer №2

To provide a more detailed explanation of how @user289520's solution works:

  • Subscriptions: Serve as a way to manage disposable resources, such as the execution of an Observable. A Subscription has a key method called unsubscribe, which simply disposes of the resource associated with the subscription.

In order to efficiently unsubscribe from multiple subscriptions at once, you can gather them in the ngOnDestroy() lifecycle hook.

  • ngOnDestroy(): Executes cleanup tasks right before Angular destroys the directive/component. This involves unsubscribing from observables and detaching event handlers to prevent memory leaks.

Aside from using this.subscription.unsubscribe;, another approach is utilizing a foreach loop shown below:

this.subscriptions.forEach(s => s.unsubscribe());

Why is it crucial not to overlook calling unsubscribe() in angular.js?

  • Promises operate eagerly and are executed immediately, whereas Observables are lazy and only trigger execution upon being subscribed to.
  • Promises function in an inherently asynchronous manner, while Observables can exhibit both synchronous and asynchronous behavior.
  • Promises are designed to return a single value akin to a function, whereas Observables have the capability of returning zero, one, or multiple (potentially infinite) values.

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

Broadcast the latest N occurrences

I am working on an Angular 6 application where I want to display the most recent N events from a continuous stream of events coming from a web-socket. Currently, the data is shown using RxJS Observable<Event[]>: <div *ngFor="let event of (wsEven ...

Can someone provide guidance on creating a Primeng Generic Group Array?

Here is my original object: users = [ {id: 1, name: "name1", company: "com1"}, {id: 2, name: "name2", company: "com2"}, {id: 3, name: "name3", company: "com1"}, {id: 4, name: "name4", company: "com2"}, {id: 5, name: "name5", company: "com3"}, ] ...

Significant bloat in main.js file detected in Angular 2 application compilation

I developed an application using <a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="65040b02100904174806090c25554b554b565c">[email protected]</a>. The app is a transformation of a basic Angular 1 application. My conc ...

Defined interface with specific number of members

I am tasked with creating an interface that has only two members, one of which is optional and both have undefined names. Something like: interface MyInterface { [required: string]: string|number [optional: string]?: string|number } Unfortunately, ...

Angular-cli and Chrome extension compatibility causing unexpected UI problems post-build

I developed an application with a sticky header at the top using angular2 mdl layouts. Recently, I made changes to the code to create a more customizable header. However, after building the app (ng build) and importing it as an unpacked extension, the con ...

Angular is having trouble recognizing the URL with index.html#

Let me explain the scenario I'm dealing with. I need to update the AngularJs code to Angular 7 as per a new requirement. One of the pages in the application deals with password retrieval. The process for retrieving the password is outlined below: ...

Exploring the topics of Subjects in RxJs and EventEmitters in Angular2

Can you explain the distinction between these concepts, along with guidance on when and how to utilize them? I've come across the idea that Subject is akin to an EventEmitter. If I aim to rephrase this information, what approach should I take? impor ...

The view fails to update when the object is modified

Within the acceptRequest function in child.component, the commissioner.requestAccepted property is set to false, and then the updated commissioner object is returned. Ideally, I want the button to be automatically removed from the view once the object is ...

Ways to implement the React.FC<props> type with flexibility for children as either a React node or a function

I'm working on a sample component that has specific requirements. import React, { FC, ReactNode, useMemo } from "react"; import PropTypes from "prop-types"; type Props = { children: ((x: number) => ReactNode) | ReactNode; }; const Comp: FC< ...

The angular-oauth2-oidc library is having issues loading the jsrsasign module

I'm currently working on upgrading a dependency in Angular for a project that was forked from: https://github.com/mgechev/angular-seed The dependency in question is located at: https://github.com/manfredsteyer/angular-oauth2-oidc. However, I'm f ...

What is the best way to define a precise return type for a JSX Element?

Is it possible to define a function that returns a Button element and what would the correct return type of the function be? For example: Ex: const clickMeButton = (): Button => { return ( <Button> Click Me </Button& ...

Restrict the number of API calls in nestjs

Is there a way to effectively limit the rate of my nestjs api calls? So far, I have explored various packages, but they all seem to limit based on the user's IP address. Do you happen to know of any package that can achieve rate limiting using the us ...

Participating in consolidated data

I need to merge data from my trainings-table with my users-table. The structure of the data is as follows: - users - key1 - name - trainingIds - t_key1 - t_key3 - trainings - t_key1 - name - description - t_k ...

Is it possible to reference and assign controllers from templates in Angular 2 like in previous versions?

In my opinion, one of the great things about Angular 1 is that developers can write business logic in controllers without having to reference anything related to markup or rendering. After reading the Angular 2 documentation, I came across this code snipp ...

Angular 4 allows the addition of an image from right to left upon clicking

I've been working on angular 4 and I've successfully implemented the functionality of adding flags. However, the issue is that the flags are currently appearing from left to right. What I'm aiming for is to have the images appear from right ...

Using Azure AD for authentication: Implementing Msal authentication in a React Next.js application with TypeScript and App Router

Working on a React Next.js web application with Microsoft Authentication Library (MSAL) login integration, using Azure. The app utilizes Next.js with the App Router for routing. But encountering an error when attempting to run the app: createContext only w ...

Discovering the right category for a general component: A step-by-step guide

How about creating a new list component that can work with an array of objects? <script setup lang="ts"> const props = defineProps<{ items: Record<string, unknown>[], selected: Record<string, unknown> | null field: stri ...

How can I avoid a component from triggering its subscription twice in Angular 5 when the component is nested twice inside another component?

How can I prevent a component in Angular 5 from triggering its subscription twice when the component is placed twice inside another component? For example, I have a NavMenuComponent with two instances of a cart in its template. <!-- cart 1 in n ...

I encountered an issue when trying to call a class in angular 2, receiving the error message "Supplied parameters do not match any

A new class named items-class.ts was successfully created: export class ItemsClass { constructor(public name:string, public desc:string, public stat:string){} } To implement this class in a component called app.component.ts: import { Component } fro ...

Require a parameter in the return function when the generic is not null in the caller within Typescript

In TypeScript version 5.0.2 I am working on a function that returns an array of 3 functions. I want the purchase function to be typed in such a way that it only requires a requirement parameter if the specified product has one (as indicated in the product ...