I am seeking guidance on how to manually provide data to an rxjs observable. Can anyone help me with this basic question?

I am interested in using an observable to communicate "exceptional states" to different parts of my Angular application, but I am struggling to grasp their functionality.

In the code snippet below, I have created an observer object and turned it into an observable. My goal is to learn how to invoke the "next" method outside the Observable.create method so I can inject custom events into the stream. Trying to call next directly on the observer doesn't seem to provide the solution.

 var observer = {
          next: function(value) {
            this.myvalue = "last value: " + value;
          },
          error: function(error) {
            console.log(error);
          },
          complete: function() {
            console.log('completed');
          },
          myfunction: function() {
            this.myvalue = "Penguins"
          },
          myvalue: ""
      }

     let myobs$ : Observable<any> = Observable.create(function(obs) {
        obs.next("Some foo");

        obs.next("Other foo");
      })

      let foo = myobs$.subscribe((observer) => {
        console.log("This is the subscription: ", observer)
      })

      setTimeout(function() {
        observer.next("This is a late breaking value");
        console.log(observer.myvalue);
      }, 2000);

  }
  

This particular code snippet generates the following console output:

This is the subscription:  Some foo
    This is the subscription:  Other foo
    last value: This is a late breaking value
    

It appears that calling next directly on the observer object (which I attempted within the timeout function at the end) does not deliver a value within the subscription.

It is evident that I am struggling to understand the intended functionality of observables. I would appreciate clarity on how to manually insert data into the stream when working with an observable and how subscribers can pick up such data. While I can see how event-driven actions like mouse clicks or AJAX requests trigger this, I am specifically looking to create a stream that can dynamically receive input when specific events occur at various points in my code.

Answer №1

If you're looking to enhance your understanding of RxJs, it's recommended to explore the RxJs Subject documentation. This resource will provide you with the necessary insights. The documentation explains that a Subject is a specialized type of Observable that enables values to be broadcasted to multiple Observers, akin to EventEmitters.

There are various types of subjects available including ReplaySubject, BehaviorSubject, and AsyncSubject. It is advisable to delve into the documentation or seek out tutorials to understand how and when to utilize them effectively. If you wish to emit both previous values and new values from your observable, you can achieve this through custom behaviors using pipable operators provided by RxJs. Familiarizing yourself with these operators is also recommended. For a practical example, refer to this stackoverflow post that demonstrates the exact functionality you are seeking:

Building on the example:

const subject = new Subject().pipe(
  startWith('Penguins'), // emit first value to fill buffer
  pairwise(),
  map([previous, current] => {
    return previous + current;
  }),
);

const observer = {
  next: (value) => {
    console.log(value);
  },
  error: (error) => {
    console.log(error);
  },
  complete: () => {
    console.log('completed');
  },
};

// Subjects
const subscriber = subject.subscribe(observer);

subject.next('Some foo');

Answer №2

To put it simply: it is not possible if you are generating observables in this manner. What you are actually providing as an argument to the subscribe() method is just a function that will be executed when the object's state changes. This function (and any others, as you can subscribe multiple times) will be saved, so it is crucial to remember to unsubscribe it. Observables are essentially an rxjs implementation of the Observer pattern. However, there is an alternative way to indicate changes. Rather than using variables like number or string, you can utilize Subject, BehaviourSubject, or even ReplaySubject to easily notify of state changes. Subject does not retain the value passed with the next() method, so you will only receive it if you subscribe before utilizing next(). BehaviourSubject stores the value, and upon subscribing, you will receive the most recent value. ReplaySubject functions similarly to BehaviourSubject, but it will emit the n latest values.

Update: Technically, it is possible, but you must save the function you are passing as a callback to Observable.create, and you can use next outside of the Observable to send data. Nevertheless, I highly recommend utilizing Subjects.

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 create and implement custom declaration files that are not available on @types or DefinitelyTyped?

I have encountered a situation where I am using an npm package named foo that is not available on DefinitelyTyped or may be outdated. Despite this, I still want to consume it under stricter settings like noImplicitAny, so I need to create custom definition ...

Discover the utility of the useHistory() hook in TypeScript for Class Components

Hello there, I am currently attempting to implement the following code snippet in my TypeScript-based class component: this.history.push({ pathname: `/search-results`, search: `${job}$${location}` } ...

Angular 8 does not allow for the assignment of type '{}' to a parameter

I have a unique approach for managing errors: private handleErrors<T>(operation = 'operation', result?: T) { return (error: any): Observable<T> => { console.error(error); this.record(`${operation} failed: ${error.m ...

How to conceal an element in Angular using its unique identifier

I am looking for a way to toggle the visibility of an element based on its ID. I have a dynamic list with the following structure in my TS component: vehicles = [ { "id": 1, "type": "car", ...

Formulate a multi-line string using a collection in React's JavaScript framework

I'm working on a React function that involves a set and I need to update an HTML element using the data from this set. Below is an example of my code: const updateElement = (mySet) => { document.getElementById('myId').innerHTML = Arra ...

In Typescript, object strings can be enforced to be used from the parent object similar to

I am currently developing an API wrapper for a lower level library that utilizes enums to map human readable keys to internal values. In order to enhance security, I want to only use the enum keys and not the underlying values in any logging or other funct ...

Universal function for selecting object properties

I've recently delved into TypeScript coding and have run into a puzzling issue that has me stumped. Take a look at the code snippet below: interface testInterface { a: string; b: number; c?: number; } const testObject: testInterface = { a: & ...

Vercel deployment encountered an AxiosError with a status code of 404

I am currently working on an API route called app/api/posts/route.ts, which is responsible for fetching all posts from my database using Prisma ORM. In the localhost environment, the database is hosted on my local PostgreSQL server. However, in production, ...

Launch a fresh window in Angular application without the need for a complete restart

How can I open a new window in Angular while passing values in the route to call an endpoint without causing the entire application to reload? It feels like such a hassle just to display a simple HTML page. Is there a better way to achieve this? ...

Send out data every 250 milliseconds in a way that resembles debounceTime(), but without any waiting period

When the window is resized, I have a complex operation that rearranges multiple DOM elements. To prevent frequent updates, I implemented debounceTime(250ms) to introduce a delay before refreshing the components. However, this approach can cause issues if ...

Error: Cannot use Object.fromEntries as a function

I encountered an issue with some older iPhones, specifically iPhone 7 and iPhone 10. https://i.sstatic.net/gX32N.png I have been unsuccessful in finding a solution to this problem. The libraries I am utilizing "@chakra-ui/react": "^1.4.1 ...

Obtain the string value for the template variable

Trying to display a string literal if element.elementId is null or undefined. <div>{{String(element.elementId)}}</div> Encountering an error: TableBasicExample.html:6 ERROR TypeError: _co.String is not a function at Object.eval [as updat ...

Ensuring that a TypeORM column has been updated

Currently, I am utilizing TypeORM with the ActiveRecord design pattern and have created this entity: @Entity() export class User { @PrimaryGeneratedColumn() public id: number; @Column() public username: string; @Column() public password: stri ...

Hover Effect for 3D Images

I recently came across an interesting 3D Hover Image Effect that I wanted to implement - https://codepen.io/kw7oe/pen/mPeepv. After going through various tutorials and guides, I decided to try styling a component with Materials UI and apply CSS in a differ ...

When a form contains a ViewChild element, changes to the ViewChild element do not automatically mark the

Let's set the stage: MainComponent.html <form #someForm > <input type="text" name="title" [(ngModel)]="mainVar" /> <child-component /> <input type="submit" [disabled]="someForm.form.pristine" /> </form> ChildComp ...

Group multiple typescript files into separate outFile modules

Can TypeScript files be grouped into multiple outFiles? I want to bundle my Typescript code, but instead of one single JS file, I would like to organize my TS into separate JS files such as controllers.js and plugins.js. The options in the TypeScript pro ...

What will be the output of this typescript function?

Whenever I hover over the keyword 'function', this cryptic description pops up: "(local function)(this: any, next: (err?: mongoose.CallbackError | undefined) => void): Promise<void>" I'm confused about whether it return ...

What steps should I take to instruct TypeScript to package a third-party library from the node_modules directory?

I am looking to configure the TypeScript Compiler in such a way that it utilizes node_modules/firebase/firebase.d.ts for typechecking my code, and also includes node_modules/firebase/firebase.js in the files where I import firebase functionalities. Althoug ...

Unable to iterate over property in Angular 6 after receiving response

Recently, I started working with Angular and encountered an issue while trying to loop through a property in the component file. I kept receiving an error message stating that the property length is undefined. Check out this screenshot from Chrome DevTool ...

Angular tests are not reflecting HTML changes when there is a modification in the injected service

I'm currently testing a component that dynamically displays a button based on the user's login status. The user details are obtained from a service method, and the component uses a getter to access this information. Inside the component: get me ...