Disadvantages of utilizing subjects as observables

Do you ever question the necessity of using the "asObserveable()" method on a subject?

In my opinion, it seems to result in significant unnecessary overhead. The restrictions on methods like "next()" or "complete()" appear pointless to me.

Is there a compelling reason for doing this that you can share?

Let's compare two scenarios:

  1. With asObservable()
export class TestService {
     public get test$(): Observable<test> {
        return this.test$.asObservable();
     }
    
      public get test2$(): Observable<test> {
        return this.test2$.asObservable();
      }
    
      public get test3$(): Observable<test3> {
        return this.test3$.asObservable();
      }
    
      public get test4$(): Observable<test4> {
        return this.test4$.asObservable();
      }
    
      private readonly _test1$ = new ReplaySubject<test1>(1);
      private readonly _test2$ = new ReplaySubject<test2>(1);
      private readonly _test3$ = new ReplaySubject<test3>(1);
      private readonly _test4$ = new ReplaySubject<test4>(1);
 }

  1. Without asObservable()
 export class TestService {  
      public readonly test1$ = new ReplaySubject<test1>(1);
      public readonly test2$ = new ReplaySubject<test2>(1);
      public readonly test3$ = new ReplaySubject<test3>(1);
      public readonly test4$ = new ReplaySubject<test4>(1);
}

Answer №1

Drawbacks of Using subject's asObservable Method

There is some repetitive code involved, but not much else to consider.

From my perspective, it adds unnecessary overhead.

Have you conducted any measurements on this? Subjects are merely extending Observables, resulting in just a shallow copy being created. It would be surprising if you could identify a significant difference in performance in practical scenarios.

Advantages of Utilizing subject's asObservable Method

A cleaner architecture leads to easier bug detection and prevention during development.

Encapsulation plays a crucial role in maintaining a clean architecture. By concealing certain parts of the program from others, each component becomes simpler to comprehend. This consequently facilitates understanding, coding, expanding, and managing tasks.

In a well-structured system, the scope of potential bugs is significantly reduced.

In most cases, these benefits become more evident in larger projects with sizable teams. For personal or small team projects aimed at creating a minimum viable product quickly, excessive planning may be set aside for faster progress. While such projects may require rewrites or updates as they grow, the additional effort will prove valuable by then.

Alternatives to subject's asObservable Method

If you have a strict static type checker in place (like TypeScript, Elm, PureScript, ClojureScript, etc), you can simply return the Subject as an Observable without affecting the runtime representation of the type.

This approach maintains encapsulation without introducing any runtime costs.

Answer №2

Let's consider a scenario where you need to trigger an event named execCompleted$ based on a specific action. Here is how it can be implemented:

export class TestService {
 private readonly execCompleted$ = new Subject<string>();

 public async makeServerCall(userData){
   const resp = await this.http.post('...').toPromise();
   this.execCompleted$.next(resp.data.id);
   return resp;
 }

 public getUpdatedId(){
   this.execCompleted$.asObservable();
 }

}

This service is utilized by two Components -> Admin and UserInfo.

The Admin component can update user information through makeServerCall() which triggers an event that needs to be captured by the UserInfoComponent for updating the data accordingly.

By making use of getUpdatedId() to expose the Subject, only authorized components can emit the next() event on execCompleted$. This ensures that the Subject is only triggered when makeServerCall(userData) is invoked.

While this example may seem basic, it illustrates a common practice in programming to prevent unauthorized events from being emitted or canceled. The goal is to enforce restrictions on what can be extended by others and what cannot, similar to the open-closed principle.

The aim is to restrict unwanted events from being triggered and ensure that only the intended source has the capability to do so.

Such practices are essential in maintaining code integrity and preventing unintended actions from occurring.

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 serialize data from non-form elements and make it easily accessible through params[:model]?

I have developed a unique Sinatra application that leverages an external API to load data and exhibit it on a page. Utilizing Sinatra, the information is retrieved and stored in a temporary model instance (which is NOT saved) for seamless access to all its ...

What is the best way to completely clear $rootScope when a user signs out of my application?

In my development work, I frequently find myself using $rootScope and $scope within controllers and services. Despite searching through numerous Stack Overflow answers for a solution to clear all $scope and $rootScope values, such as setting $rootScope t ...

Refresh the page only when on the initial page of the pagination

I've been utilizing this jQuery code with AJAX for pagination purposes. Currently, I am fetching data from a PHP file that displays limited information. Here is the index file snippet: <script type="text/javascript"> $(document).ready(fun ...

The Material UI button feature neglects to account for custom CSS styles when attempting to override the default settings

Utilizing a custom bootstrap css styles in my react app, I am seeking to enhance the default material ui components with the bootstrap styles. import React, {useState} from 'react'; import 'cg-bootstrap/core/build/cg-bootstrap-standard.css&a ...

What is the best way for me to use a ternary operator within this code snippet?

I'm in the process of implementing a ternary operator into this snippet of code, with the intention of adding another component if the condition is false. This method is unfamiliar to me, as I've never utilized a ternary operator within blocks of ...

I'm unsure of the date format, could you guide me on how to convert it?

Dealing with formatting timestamps can be tricky, especially when you have different formats to work with. For instance, my AngularJS plugin returns timestamps in this format when printed in the JavaScript console: Sun Mar 30 2014 14:00:56 GMT-0400 (Easte ...

Interconnected props in Material UI components interact with one another

Is there a way to have the value of one property in a Material UI component reference another property within the same component? For example, can I make the value property in a Switch component refer to the checked property? <Switch checked={sing ...

Issues have been identified with React Native UI components RCTBubblingEventBlock and RCTDirectEventBlock not functioning as expected

In my custom native view within an Ignite project, I am facing a challenge with setting up communication from Objective-C to React Native. While the communication from React Native to iOS works using HTML injection, the reverse direction is not functioning ...

Utilizing JavaScript to eliminate objects from a collection and showcase a refreshed arrangement

On a simple webpage using bootstrap and js/jquery, data is fetched via ajax to create entries displayed to the viewer. The process involves: - making a request - parsing XML to create an array of objects with all the data - sorting by one property - cr ...

Execute a Gulp task automatically following the installation of an NPM package, no need for

I have created a small Angular package that is available on npmjs. I need to modify the "selector" name when installing my package, so I wrote a gulp task as shown below: gulp.task('tag-change', function () { // var files = fs.readFileSync(&a ...

Troubleshooting Typescript compilation issues following an upgrade to a React Native project

I am facing a challenge while updating a react native project from version 0.63.3 to 0.67.0. When attempting to run npm run tsc, I encounter numerous errors indicating that the typescript packages are not compatible with their original packages. Here is a ...

Tips for enlarging small ImageData onto a larger HTML canvas

I am facing an issue with placing image data of size 100x100 onto a canvas of size 1000x1000. Despite my efforts, I have not been able to achieve the desired result. let width=1000; //canvas width let height=1000; //canvas height let img_w=100; ...

The instantiation of generic types in Typescript

I have been working on a function that aims to create an instance of a specified type with nested properties, if applicable. This is the approach I have come up with so far. export function InitializeDefaultModelObject<T extends object> (): T { ...

Enhance your PrimeNG p-calendar by customizing the background-color of the dates

Hello, I am currently attempting to customize the appearance of the p-calendar, but I am struggling with changing the color of the displayed dates. Can anyone provide assistance? Thank you in advance. Below is my template: <div class="p-field p-co ...

Is it possible to showcase a unique date for every item that gets added to a list?

I am new to using React, so please bear with me. I want to be able to show the date and time of each item that I add to my list (showing when it was added). I am struggling to get this functionality working with my current code. Any help or explanation o ...

How can I use jQuery to set the text in a select element in HTML?

I have come across more examples of this, but unfortunately they do not seem to work. $(window).load(function () { $("#country").html('Please make a selection from the options below'); }); <select id="country"> <option value="None"> ...

Tips for swapping out a div tag with another div tag in the same spot without needing to redirect to a different page by utilizing bootstrap

Currently, I am developing a JSP project that utilizes Bootstrap for the frontend. I have come across a question regarding HTML design. Is there a way to replace one div tag with another div on the same page without navigating to a new URL using Bootstrap ...

Dynamic loading of XML data into a DIV when hovering over it

The main idea behind my project is quite simple. I have a grid of company logos extracted from an XML document using XSLT, each logo with its own unique link to the respective company profile. On the same page, I have a separate div that serves as a "prev ...

Styling an exponential number in a table header using Vuetify

I am looking to replace the default header 'number' with a custom HTML header while using vuetify for displaying a data table. My current setup looks like this: headers: [ {text: 'number', value: &a ...

Is there a way to incorporate a callback function for animation in cgscenegraph?

After creating my animation, I am interested in incorporating a callback function when the loop of the animation comes to an end. Is there a way you can guide me on achieving this? Thank you. ...