The directive subscription remains inactive even when the subject triggers the next function

Plunkr: https://plnkr.co/edit/KfPfVSbZm087uIPvFEkM?p=preview

I have developed a service that serves as an API for a modal component. In addition, there is a directive available that can be used to apply a class to any element when the modal is open. However, I am facing an issue where the subscription inside the directive does not trigger no matter what I try.

I attempted using both Subject and BehaviorSubject, but neither seems to work.

Service:

@Injectable()

export class ModalApiService {

  constructor() {}

  private states = new Subject<any>();

  states$ = this.states.asObservable();

  open(id: string, template?: string): void {
    this.states.next({isOpen: true, id: id, template: template});

    // This runs as expected
    console.log(true);
  }

  close(id: string): void {
    this.states.next({isOpen: false, id: id});
  }
}

Directive:

@Directive({
  selector: '[modalState]'
})

export class ModalStateDirective implements OnDestroy, OnInit {

  constructor(private modalApi: ModalApiService) {}

  private modalSubscription: Subscription;

  @HostBinding('class.modal-open')
  isOpen: boolean;

  ngOnInit() {

    this.modalSubscription = this.modalApi.states$.subscribe(
      state => {
        this.isOpen = state.isOpen;

        console.log(this.isOpen)
      }
    );
  }

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

Answer №1

When utilizing the BehaviourSubject, everything appears to be functioning correctly and it triggers the subscribe function. However, there is a puzzling occurrence of having undefined value for the object properties, even though logging the object shows no issues.

import 'rxjs/Rx';
import {BehaviorSubject} from 'rxjs/BehaviorSubject';

private states = new BehaviorSubject<any>();
states$ = this.states.asObservable();

A Case of Working and Not-Working : https://plnkr.co/edit/YspSd2fKvktPEk6bL2hF?p=preview

Answer №2

The subscription does not trigger because the ngOnInit directive is executed after the app's ngOnInit, causing the next to be called before the subscription in the directive. This can be demonstrated by a simple button that calls the service open/close methods:

toggle() {
  this.modalApi.open('someid');
  this.modalApi.close('someid');
}

Check out the demo: https://plnkr.co/edit/MJET0Jw12SLx0BChAiWz?p=preview

If you want to start with an open Dialog using the service, consider using a ReplaySubject. This will provide all emits before the first subscriptions are made:

Learn more about ReplaySubject here: https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/subjects/replaysubject.md

Here is a demo showcasing the use of the ReplaySubject: https://plnkr.co/edit/boHGQhc7atMTOTPLMnO0?p=preview

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

Angular2 app is sending empty HTTP headers to the server

My REST api, built using SpringBoot, incorporates JWT for authentication and authorization. To achieve this, I utilize a FilterRegistrationBean. Within this setup, there exists a class called JwtFilter that extends GenericFilterBean. This class is respons ...

What is the best way to display a popup message confirming successful login validation?

I want to implement a login success popup that only appears after validation and user verification. Currently, the popup is displaying before validation upon clicking the submit button. I want the popup to show only after successful validation and user v ...

Create a versatile generic object using TypeScript

Looking to create a versatile onFilterChange helper function that works for all filters, eliminating the need to write it out separately each time. However, I've hit a snag: // helper.ts export function onFilterChange(prevState: Record<string, any& ...

Trigger a PrimeNG p-datatable event when a new row is inserted

My p-datatable is linked to a list of entries. I am trying to focus on newly created rows dynamically, specifically on an input within the new row. How can this be achieved? Every time a new entry is added to the list, a new row is appended in the datatab ...

TS2559: Type 'String' lacks any common properties with type 'object'

When working with TypeScript, I encountered an issue with a map defined as shown below that is intended to accept (key, value) pairs of (string, anything). let map = new Map<String, Object>() Upon attempting to insert a (key, value) pair into the ma ...

Combining Bootstrap admin template with SCSS styling in Angular 2

Currently seeking a complimentary bootstrap template featuring scss style to incorporate into my angular project. Is there anyone who can guide me on the correct procedure for this task? I stumbled upon a potential template on github but I am having diffic ...

Angular 2 regex for validating FQDN/URL formats

As a beginner in regex, I'm looking for help with validating fully qualified domain names (e.g. mysite.com) or a URL without checking the protocol. Can anyone provide a regex expression or suggest where to find one? ...

Ways to employ a Hyphen(-) to connect two strings within an ngIf condition in Angular 9

I'm dealing with an IF condition in HTML that checks for permission to access a specific page: *ngIf="permission?.product-report?.list_product_report" The name "product-report" is static and directly used in the condition. However, whe ...

Why is the imported package not being recognized in the namespace declaration of my Node.js TypeScript file?

Currently, I am utilizing the WebStorm IDE developed by JetBrains to modify a TypeScript file within a Node.js v8.6.0 project. The JavaScript version set for this project is JSX Harmony. In the beginning of the TypeScript source file, there is an import st ...

Angular: the page continues to display outdated information after using router.navigate

My web app allows users to select products to purchase. They can pause the configuration process and resume it later. Currently, I am using localStorage to store information about the products and their prices. There is a page in my app that displays a ta ...

Crafting a recursive Typescript Immutable.js Record through typing

I am currently working on representing a tree-like data structure using immutable js and typescript. At the moment, I am utilizing regular vanilla js objects to depict the nodes within the tree. Below is the type signature. type NodeType = { value: str ...

Exploring the method to deactivate and verify a checkbox by searching within an array of values in my TypeScript file

I am working on a project where I have a select field with checkboxes. My goal is to disable and check the checkboxes based on values from a string array. I am using Angular in my .ts file. this.claimNames = any[]; <div class="row container"> ...

Encountering an error when using the Vue 3 TypeScript Composition API for style binding with an asynchronous

I utilized nexttick alongside an async method to update a DOM element. However, I am encountering issues with returning the correct style type. An error message pops up stating: error TS2322: Type 'Promise<{ maxHeight: string; }>' is not ...

What is the best way to revert a screen's state back to its original state while utilizing react navigation?

How can I reset the state in a functional component back to its initial state when navigating using navigation.navigate()? For example, if a user navigates to screen A, sets some state, then clicks a button and navigates to screen B, and then goes back to ...

Tips for setting up a personalized preview mode in Sanity Studio using Next.js

I am facing an issue displaying the preview mode because the URL must contain specific parameters such as "category" and "slug" (as shown in the image below). Here is the error URL with undefined parameters Therefore, I am unable to retrieve the paramete ...

Transforming Angular 2 quickstart application for deployment on Google Cloud infrastructure

Attempting to deploy a basic project on Google Cloud platform has proven to be more challenging than expected. The simple quickstart project can be accessed here, and functions flawlessly locally. While there are other providers like Heroku that offer one ...

Angular 2 implementes a loading spinner for every HTTP request made

My objective is to implement a spinner functionality whenever an HTTP request occurs in my Angular app. Essentially, I want the user to see a loading screen during these requests within my app component. The setup for my spinner component and spinner servi ...

Tips on concealing the scrollbar only when a particular element is visible

I inserted the following code into my index.html file: <head> <style> body::-webkit-scrollbar { display: none; } </style> </head> This code successfully hides the scrollbar. My goal is to only h ...

Exploring Angular Components with Jasmine and Karma while integrating third-party tools such as ExcelJS

Currently tackling the challenge of writing tests for a project using ExcelJS. The project runs smoothly in both build and production environments, but when attempting to incorporate unit tests for certain components, I'm encountering issues with Test ...

Creating a popup trigger in ReactJS to activate when the browser tab is closed

I am currently working on an enrollment form that requires customer information. If a user fills out half of the form and then attempts to close the tab, I want to trigger a popup giving them the option to save and exit or simply exit. While I have a jQue ...