Access exclusive content by subscribing now!

How can I return a reference to a subject from a service without allowing the receiver to call .next() on the subject?

Let's say there is a service with a subject that triggers new events.

class ExampleService {
  private exampleSubject = new Subject<boolean>;

  // Method to trigger next on the subject
  doNext() {
    this.exampleSubject.next(true);
  }

  getSubject() {
    // Return reference to the subject for subscribing only, not modifying
    return this.exampleSubject;
  }
}

I want other components to be able to subscribe and listen for changes but prevent them from making changes to the subject directly.

ExampleService.getSubject().subscribe(() => {
  //do something 
}) // allowed
ExampleService.getSubject().next(true) // not allowed/error

Answer №1

For anyone using TypeScript, the recommended approach to achieve this is by converting the Subject to an Observable:

class ExampleService {
  private exampleSubject = new Subject<boolean>();
  observable$: Observable<boolean> = this.exampleSubject;

  ...
}

By making observable$ public, it becomes a regular Observable. TypeScript will prevent you from calling methods like

ExampleService.observable$.next()
because they are not available on Observables.

If you are working with JavaScript only, you can utilize exampleSubject.asObservable() to transform a Subject into an Observable.

The discussion on RxJS's GitHub regarding this topic can be found here: https://github.com/ReactiveX/rxjs/pull/2408

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

Incorporate an Ajax request onto an existing link within a div element

Here is what I have: <div id="div-for-ajax-onclick"> <a href="http://www.google.com">Link to google</a> </div> $("#div-for-ajax-onclick").click(function() { // update database }); I am looking for a solution where if someone c ...

Enums are not recognized by TypeScript when used within an array

I have defined an enum as follows: export enum Roles { ADMIN, NONE; } An object is being used which utilizes this enum. The structure of the object is: export interface User { name: string; roles: Roles[]; } Upon fetching this object via a web r ...

Extracting IDs, classes, and elements from a DOM node and converting it into a string format

Can someone please guide me on how to extract the DOM tree string from an element? Let's consider this HTML structure: <div> <ul id="unordered"> <li class="list item">Some Content</li> </u ...

Using the ref callback to access getBoundingClientRect values in React Components

I'm having some trouble extracting data using the getBoundingClientRect() method from a set of animated div elements. The issue I'm facing is that the refCallback function is returning empty DOMRect objects. If you're interested, feel free t ...

Exporting modules in Node.js allows you to use functions

Can you explain why this code snippet is successful: exports.foo = 'foo'; var bar = require('./foo'); console.log(bar); // {foo: 'foo'} While this one fails to produce the desired output: var data = { foo: 'foo' ...

Having trouble with jQuery animate function?

I have been struggling to get my animate function to work, despite looking at multiple similar posts and making modifications to my code. My goal is to make an image of a plane move from left to right across the screen and stop halfway. Here is the code I ...

Incorporating the id attribute into the FormControl element or its parent in Angular 7

I'm attempting to assign an id attribute to the first invalid form control upon form submission using Angular reactive forms. Here is my current component code: onSubmit() { if (this.form.invalid) { this.scrollToError(); } else { ...

The absence of req.body in the app reflects an undefined state

I'm encountering an issue with my app and I believe showing you my code is the best way to explain the problem: var Meetup = require('./models/meetup'); module.exports.create = function (req, res) { var meetup = new Meetup(req.body); c ...

Add a message displaying the error in the input field using jQuery Validation

Is there a way to append the jQuery Validation error messages to the input field or get help with positioning them properly? The random popping up of error messages is causing chaos in the form layout. I prefer to have the error messages displayed undern ...

When submitting a form with the jQueryForm plugin, take action on the form by selecting it with `$(this)`

I have a situation where I have multiple forms on one page and am utilizing the jQuery Form plugin to manage them without having to reload the entire page. The issue arises when I need some sort of visual feedback to indicate whether the form submission wa ...

The incredible power of the MongoDB $inc field

I am facing a challenge in writing a function that accepts a record id, an action (inc or dec), and a field name as a string to be incremented (can be 'likes', 'subs' or any other). The issue is that I am unable to find a way to replac ...

Vue.js parent component not receiving data emitted by child component

Below you will find the child and parent components. I am struggling to pass data from the child component to the parent component. Can you help me pinpoint where the issue may be? Child Component <template> <div> <v-btn class="r ...

Substitute this.bindMethod for function component

I have a class component that is structured like this: interface MyProps { addingCoord: any resetCoords: any } interface MyState { x: any y: any } class DrawerOld extends React.Component<MyProps, MyState> { width: number height: number ...

Using TypeScript: Union Types for Enum Key Values

Here's the code in the TS playground too, click here. Get the Enum key values as union types (for function parameter) I have managed to achieve this with the animals object by using key in to extract the key as the enum ANIMALS value. However, I am s ...

Just initiate an API request when the data in the Vuex store is outdated or missing

Currently, I am utilizing Vuex for state management within my VueJS 2 application. Within the mounted property of a specific component, I trigger an action... mounted: function () { this.$store.dispatch({ type: 'LOAD_LOCATION', id: thi ...

Navigating resolvedUrl with getServerSideProps in the newest version of NextJS - a comprehensive guide

Is there a way to obtain the pathname without using client-side rendering? I have been searching for information on how to utilize the getServerSideProps function, but so far with no luck. Initially, I attempted to employ usePathname; however, this result ...

Using jQuery to create dynamic elements that fade out with timers

My website has a simple message system that displays messages in a floating div at the top of the page. Each message is supposed to fade out after a certain amount of time, but I want users to be able to pause the fading process by hovering over the messag ...

When the value of a Formcontrol is changed using valueAccessor.writeValue(), it remains unchanged

Encountering a similar issue as seen in this stack overflow post, but the solution provided isn't resolving the issue. Perhaps you can offer assistance on that thread. In my scenario, I have created a directive for formatting phone numbers: import { ...

Is there a specific method for organizing cached buffer conversions in Node.js for optimal efficiency?

In a GitHub discussion, it was pointed out that the Map's .has method does not work with buffers because identical buffers are considered as distinct objects. This limitation became apparent when attempting to store buffer string conversions in a map ...

Dealing with issues escaping unicode characters in JavaScript

Whenever I need to load data from an external file based on a specific event, I make use of the following jQuery code: $("#container").load("/include/data.php?name=" + escape(name)); An issue arises when the JavaScript variable "name" contains Unicode ch ...