Is it considered beneficial to use Observable as a static class member?

Lately, I have been diving into a new Angular project and noticed that the common way to share state between unrelated components is by using rxjs Subject/BehaviorSubject as static members within the class.

For instance:

export class AbcService {
  private static importantData: Subject<any> = new Subject();
  
  static get importantData$(): Observable<any>{
    return AbcService.importantData.asObservable()
  }
}

How it's used:

@Component({
  ...
})
export class DefComponent {
  constructor() {
    AbcService.importantData$.subscribe(...)
  }
}

I've been racking my brain trying to understand the benefits of this approach but struggle to see any real value in it, especially considering it goes against the injection concept.

Am I missing something here? What advantages come with declaring observables as static class members?

Answer №1

Correct, there is no added benefit to this particularly with Angular since services are already singleton and do not require it.

Nevertheless, it may prove valuable in situations outside of the Angular framework.

Answer №2

The advantage here lies in the functionality of any static method - it can be invoked without needing to create an instance of the class. The drawback, however, is that any static class property used by the static method will be shared across all invocations.

Interestingly, in this scenario, the limitation itself turns into an advantage - ensuring that the service originates from a single source. This proves helpful when dealing with non-injectable services that are not singletons.


I have developed a specific library for this purpose. It facilitates the creation of broadcasters for disseminating data to multiple recipients, or listeners to receive data from various senders.

Moreover, the library offers additional functionalities like creating a receiver prior to the broadcaster (enabling broadcasting from a dynamically loaded component to a static one), namespaces, receiver scoping, etc.

This library significantly streamlines such scenarios.

Access the library here: https://www.npmjs.com/package/ng-interconnect

Below is an example for creating a broadcaster:

 let messageStream: IMessageStream = createBroadcaster('home/stateChanged');   //Create a broadcaster
'''
/*Receive from it from another component somewhere in the hierarchy*/
 
 let userReceiver = receiveFrom('home/stateChanged', 'contacts/user', (data, error, complete) => {
  console.log(data);
  console.log(error);
  console.log(complete);
 })
 '''
 /*Broadcast messages from the first component*/
 messageStream.emit('logged-in');

Answer №3

Avoid that approach as it may not be effective in the long run. It is crucial for the class to be easily testable. The class should be able to reveal its dependencies without having to examine its code. For example, DefComponent relies on AbcService, but this information is not immediately evident just by looking at the code. Furthermore, renaming a static class means updating all files that use it, which can be cumbersome and prone to errors. A more suitable solution would be to implement a factory pattern or interface, making the class easier to test and revealing its dependencies clearly. I recommend familiarizing yourself with the SOLID Principles. https://en.wikipedia.org/wiki/SOLID

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

Adjust the zoom level when a location is detected using Mapbox

I have been reading through the leaflet documentation and it mentions using the maxZoom option for location, but I am having trouble getting it to work (http://leafletjs.com/reference.html#map-locate-options). Whenever a user uses geolocation on my websi ...

RAZOR - Strip image elements from variable with HTML content

In the code snippet below, I am using a helper to display content: @Html.Raw(Model.PageData.PageContent) My goal is to filter out any image tags that may be present. I have explored methods like .substring(), but they require specific indices or string n ...

Complete set of keys within a type

In my TypeScript project, I am working with an API (specifically OData API) to retrieve data. This API allows the selection of specific fields to retrieve. For example, api/some/getbyid(42)?$select=x,y,z can be used to get fields x, y, and z, along with s ...

Tips for preserving line breaks when sending a message through the mail

Hi, I'm currently facing an issue: I am trying to send text from a textarea using POST to a PHP script that will write it to a file and display it on the website. However, when I do this, the line breaks disappear and the displayed text ends up lookin ...

Node.js - updating the value of a exported integer variable

In my file A.js, I have defined a module-level variable called activeCount and exported it using module.exports. In another file named testA.js, I am attempting to access and modify the value of activeCount. Despite my efforts, changes made to activeCount ...

Setting up routes in VueJS and NodeJS Express for API integration: a comprehensive guide

My API routes always return HTML instead of JSON, despite trying numerous solutions that have all failed. Here is my current setup: // app.js const express = require("express"); const app = express(); const history = require("connect-history-api-fallback ...

unable to get ng-model and ng-options to function properly

Can anyone assist me with my issue? I can't figure out why it's not working. I want to generate a select dynamically from the Level[] retrieved from the database <select> <option>1</option> <option>2</option&g ...

The hover effect is not activated by the mouse movement event

I previously encountered an issue related to flickering with an absolute div when moving my mouse, which I managed to resolve by increasing the distance between my mouse pointer and the div. Now, I am working on the next phase of my project: My goal is t ...

Comparing AngularJS and Node JS in serving web pages, which is better?

Currently, I'm in the process of learning how to develop a web using angular and node JS. One aspect that I am struggling with is determining where to acquire the URLs for links. After doing some research on stack overflow and various tutorials relate ...

"Encountered an issue with ng-annotate during processing

I'm attempting to utilize ng-annotate on my Angular application, but it seems to be not working at all. Here is the configuration part: (function () { 'use strict'; angular.module('app') .config(/*@ngInject*/ ro ...

Reactjs - Creating a video component with a placeholder that loads the video seamlessly

I created a Video component that utilizes the React.Suspense component to show a placeholder while the video is loading. However, I'm facing an issue where it seems like the functionality isn't working as intended. When I set the network to "slow ...

Should we avoid using 'RedirectToAction' with AJAX POST requests in ASP.NET?

As a newcomer to jQuery, Json, and Ajax, I am putting in the effort to grasp the concepts clearly, but I am facing some difficulties. I have an ajax POST Delete method that is currently functional, however, my professor has suggested that I refactor the c ...

Unable to transfer Vue.js components in and out of the project

I have a directory structured like this. VueTree components Classic.vue Modern.vue index.js The Classic and Modern components consist of a template, export default {}, and a style. I am importing both of them in index.js as: import Classic ...

Ways to Close a Modal in Ionic 5

I have a scenario where I need to open a modal, perform an asynchronous action, and then automatically dismiss the modal once the action is completed. Specifically, I want to use the fetchData function to handle the async task. @Component({ }) export cla ...

reading an array of objects using typescript

Trying to retrieve an object from an array called pVal. pVal is the array that includes objects. I am attempting to obtain the value of "group" based on the id provided. For instance, if the id is equal to 1, it should display "VKC". Any assistance woul ...

Clicking to fade in and out with jQuery on data attributes

I have structured my HTML code as follows: <div class="col-sm-8"> <img id="click-1" class="glasses one active" src="<?php bloginfo('template_directory'); ?>/assets/images/Statesman-Three.png"/> ...

Is it possible to establish role-based access permissions once logged in using Angular 6?

Upon logging in, the system should verify the admin type and redirect them to a specific component. For example, an HOD should access the admi dashboard, CICT should access admin2 dashboard, etc. Below is my mongoose schema: const mongoose = require(&apo ...

Is it possible for me to enhance Object, Function, Date, and other similar entities in Node by adding "static methods"?

When creating a Node.js module called "augs" that includes: Object.foo = "bar"; And then entering the following commands in the REPL: require("./augs"); typeof Object.foo The result returned is 'undefined'. In our web application, we have a ...

Having trouble with the installation of nodemon globally on macOS Mojave?

When using the Visual Studio Code terminal, I ran the following command: npm install -g nodemon The output in the terminal showed: npm WARN checkPermissions Missing write access to /usr/local/lib/node_modules npm ERR! code EACCES npm ERR! syscall access n ...

Retrieving Information from Ajax Response Following a Successful Insert Query in Codeigniter

I am trying to use ajax method to insert form data into a database and then redirect it to the next page. I have successfully passed the data in ajax and inserted it into the database table. However, I am facing an issue with getting the generated referenc ...