Re-subscribe to an Observable that has been unsubscribed in RxJS

Utilizing a Service to periodically "ping" my server every 2.5 seconds, I am able to retrieve the response time from the server by using observables.

My implementation also involves angular 2 and typescript.

Now, I am facing an issue where I want to be able to stop (unsubscribe) the service upon button click. Initially, this functionality works as intended. The button is designed to act as a toggle - subscribing if not already subscribed, and unsubscribing vice versa. However, I am encountering difficulties when attempting to resubscribe.

Below is the snippet of code defining my service:

export class PingService {
  pingStream: Subject<number> = new Subject<number>();
  ping: number = 0;
  url: string = url.href;

  constructor(private _http: Http) {
    Observable.interval(2500)
      .subscribe((data) => {
        let timeStart: number = performance.now();

        this._http.get(this.url)
          .subscribe((data) => {
            let timeEnd: number = performance.now();

            let ping: number = timeEnd - timeStart;
            this.ping = ping;
            this.pingStream.next(ping);
          });
      });
  }
}

The following code shows the function triggered on button click:

toggleSubscription() {   
      if (this.pingService.pingStream.isUnsubscribed) {
         this.pingService.pingStream.subscribe(ping => {
         this.ping = ping;
         NTWDATA.datasets[0].data.pop();
         NTWDATA.datasets[0].data.splice(0, 0, this.ping);
      })
      }
      else {
         this.pingService.pingStream.unsubscribe();
      }
   }

I have instantiated the PingService within the constructor of my appcomponent which then displays the data in a chart. Upon clicking the button for the first time, the service stops and no further data updates occur. Subsequent clicks yield no change despite the `this.pingService.pingStream.isUnsubscribed` returning true.

In addition, an "ObjectUnsubscribedError" is encountered upon the initial button click.

If anyone has any insights or solutions to offer, your help would be greatly appreciated! Thank you!

Answer №1

When utilizing RxJS, there is no need to constantly subscribe and unsubscribe. An alternative approach involves using Rx streams. This method involves having two streams - one named main and the other toggle. When combined, these streams will trigger events only when the toggle stream is activated.

var mainStream = Rx.Observable.interval(100).map(() => '.');

var display = document.getElementById('display');
var toggle = document.getElementById('toggle');

var toggleStream = Rx.Observable
  .fromEvent(toggle, 'change')
  .map(e => e.target.checked);

var resultStream = toggleStream
  .filter(x => x === true)
  .startWith(true)
  .flatMap(() => mainStream.takeUntil(toggleStream));

resultStream.subscribe(x => display.innerText += x);
<!DOCTYPE html>
<html>

  <head>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.all.min.js"></script>
  </head>

  <body>
    <input type="checkbox" id="toggle" checked> Check/uncheck to start/stop
    <div id="display"></div>
    
    <script src="script.js"></script>
  </body>

</html>

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

How to disable the first option in an Angular 2 select dropdown

I'm working with a select component, and here is the code snippet I have: <select name="typeSelection" materialize="material_select" [(ngModel)]="trainingplan.type" > <option [ngValue] = "null" disabled selected>Please choose a ...

Having trouble sending a post request from Angular 4 to a Laravel endpoint

I am facing an issue with my post request while trying to submit data to a Laravel action using Angular. This is my first time working with Angular and I'm encountering some difficulties. The problem lies in the fact that although the request is made, ...

How come Typescript claims that X could potentially be undefined within useMemo, even though it has already been defined and cannot be undefined at this stage

I am facing an issue with the following code snippet: const productsWithAddonPrice = useMemo(() => { const addonsPrice = addonsSelected .map(id => { if (addons === undefined) { return 0} return addons.find(addon => addo ...

having difficulties with angular subscribing to an observable

I am currently working on a service that retrieves a post from a JSON file containing an array of posts. I already have a service in place that uses HttpClient to return the contents of a JSON file. The main objective is to display the full content of the ...

What is the process for deploying a Lambda function using Terraform that has been generated with CDKTF

Currently, I am following a tutorial by hashicorp found at this link. The guide suggests using s3 for lambda deployment packages. // in the process of creating Lambda executable const asset = new TerraformAsset(this, "lambda-asset", { ...

Struggling to locate the ID linked to a specific ObjectId and encountering issues with the import function?

Can someone help me with this issue? Error Message: ERROR TypeError: answerID.equals is not a function I am unsure why I am getting this error. Here is the code snippet: import { ObjectId } from 'bson'; export class Person{ personID: Objec ...

Is excluding dependencies necessary for a modular Typescript project?

I am currently in the process of developing an NPM package for a Typescript project using gulp and browserify. The challenge I'm facing is that the consumer of the package does not utilize modules. Thus, I am working on creating a standalone bundle wi ...

Specific generic types do not incorporate abstract type context

Take a look at this code snippet: type Data = { person: { id: number; name: string; age: number } item: { id: number; name: string; price: number } transaction: { id: number; personId: number; itemId: number; quantity: number } } type Action<T ex ...

Changing an inline function to a regular function

I am currently attempting to convert the signature of an inline function to a non-inline function: const onMouseEnter = (itemName: string): void => { alert(itemName); }; Despite my efforts, the attempted conversion did not yield the desired outcome. f ...

The current directory does not belong to a Cordova project

Upon executing ionic cordova run browser --verbose within the main directory of my Ionic4 project, I encounter the error message "Current working directory is not a Cordova-based project." as shown below. I've observed that the command generates a "w ...

How can I define the True function using Typescript?

Currently, I am working on converting Javascript examples to typed Typescript as part of the "Flock of Functions" series. You can find the reference code at https://github.com/glebec/lambda-talk/blob/master/src/index.js#L152. The True function returns the ...

Unable to set a value to a TypeScript object mapping

I encountered an issue with my typescript dictionary. Whenever I try to assign a value to it, a specific error occurs. TypeError: Cannot set property 'v1/items/someItemType/someItemId/EVENT/some DataTypeId' of undefined at ...

Sending data with Angular using a POST requestorMaking a

I'm attempting to make an HTTP POST call in Angular with a body, but I'm not receiving the response I expect. callAddGroupAPI(formId, groupJSON){ let json = { "group":groupJSON } this.http.post(this.apiURL+'AddGroup/' ...

Unexpected behavior with HashLocationStrategy

I am currently tackling a project in Angular2 using TypeScript, and I seem to be having trouble with the HashLocationStrategy. Despite following the instructions on how to override the LocationStrategy as laid out here, I can't seem to get it to work ...

Is the component not being initialized when navigating through the router, but only when the browser is refreshed?

I have noticed that when I navigate using the router, the data in the page does not update. However, if I refresh the browser, the updated data is shown in the router page. I am looking for a way to reload only the component without refreshing the entire ...

Implementing a universal (click) attribute for Angular 2 in CSS

When using Angular 1, it was as easy as following this syntax: [ngClick], [data-ng-click], [x-ng-click] { cursor: pointer; } This snippet ensured that any tags with the ng-click attribute displayed a pointer cursor. How can we achieve the same effect ...

One way to incorporate type annotations into your onChange and onClick functions in TypeScript when working with React is by specifying the expected

Recently, I created a component type Properties = { label: string, autoFocus: boolean, onClick: (e: React.ClickEvent<HTMLInputElement>) => void, onChange: (e: React.ChangeEvent<HTMLInputElement>) => void } const InputField = ({ h ...

Oops! Issue encountered while trying to read the file "src/core/database/config.ts"

Need help with migrating a database in a Node Nest.JS application. When running the npx sequelize-cli db:migrate shell command, I encountered the following exception: Error details: Error: TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension ".t ...

Is there a way for me to obtain the full error message after a failed fetch request?

I'm trying to capture all errors from the fetch function, including the specific red highlighted details as a string: https://i.sstatic.net/GtHxv.png But when I catch an error in my code, all I get is "Failed to fetch." Here's what my code looks ...

What benefits do Definitely Typed TypeScript files offer for Knockout and jQuery?

I'm not sure if this is a silly question, but I was wondering if it's necessary to use definitely typed (.d.ts) versions of external libraries when working with Typescript. Currently, my code base uses jQuery and Knockout in the traditional manne ...