RxJS: Observable.never() acts like an eternal subscription

Currently, I am working with rxjs version 5.5.6.

Below is a snippet of code that showcases a specific behavior:

Observable.of(1, 2)
    .do(a => {
        console.log(a);
        let d:string = null;
        let r = d.length;  // this line throws a null exception
    })
    .catch(() => {
        console.log("error caught");  
        return Observable.never();
    })
    .subscribe();

Expected output:

1
error caught
2
error caught

Actual output:

1
error caught

The subscription terminates even though an Observable.never() is returned in the .catch(...) method chain.

Any suggestions on how to handle this?

ANOTHER SCENARIO

this.subs = Observable
    .merge(this.$searchQuery, this.$lazyQuery)
    .do(() => this.loadingPage())
    .map(filter => this.buildURL(user, app, filter))
    .switchMap(url => this.service.getItemsFromService(url))
    .map(response => this.buildPage(response))
    .do(page => this.loadedPage(page))
    .catch(() => {
        this.loadedPage(pojo.Page.EMPTY);
        return Observable.never();
    })
    .takeUntil(this.$unsubscribe)
    .subscribe();

Answer №1

The result you receive is:

1 
error caught

This occurs because the initial value triggers an error within the tap method, which then travels through the onError channel causing the sequence to stop. By using catch, you are able to capture this error and continue on to the next sequence (never), but the original sequence (of(1,2)) remains halted. Therefore, after 1 encounters an error, 2 is not processed by tap.

Once you return never in the catch block, no values are emitted and the Observable never reaches completion. If you place logs inside the subscribe function for the next, error, and complete callbacks, you will observe that they do not get executed.

Answer №2

Indeed, all the information provided by @frido is accurate. I would like to supplement that answer with the following:

If you wish to handle any errors occurring within a specific Observable (such as an HTTP request), then you must manage it within that particular Observable.

  let correct = Observable.of("correct")
  let inCorrect = Observable.throw('inCorect')

  let obs = [inCorrect, correct];
  let handledObs = obs.map(eachObs => {
    return eachObs.catch((e) => {
      console.log("Individual handler, Good Catch!");
      return Observable.of("I am tampered");
    })
  })

  forkJoin(...handledObs)
  .do(a => {
      console.log(a);
  })
  .catch(() => {
      console.log("error catched");
      return Observable.never();
  })
  .subscribe(data => {
    console.log(`data`, data)
  },(e) => {
      console.log(`error`, e)
  });

}

Check out an example here: https://stackblitz.com/edit/angular-7mmhn7?file=src/app/app.component.ts


UPDATE

Upon reviewing your code, it appears that you are attempting to log something and the returned data may not have a length property. Even in this scenario, if you wish to continue with the stream, you can add a basic try catch block within do().

  from([1, 2])
  .do(a => {
      try {
        console.log(a);
        let d:string = null;
        let r = d.length;
      } catch(e) {
        console.log(`catched under do`, e)
      }
  })
  .catch(() => {
      console.log("error catched");
      return Observable.of('catched');
  })
  .subscribe(data => {
    console.log(`data`, data)
  },(e) => {
      console.log(`error`, e)
  });

See an example here: https://stackblitz.com/edit/angular-bcrava?file=src/app/app.component.ts

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

Determine data types for functions in individual files when using ElysiaJS

Currently, I am utilizing ElysiaJS to establish an API. The code can be found in the following open-source repository here. In my setup, there are three essential files: auth.routes.ts, auth.handlers.ts, and auth.dto.ts. The routes file contains the path, ...

Issue with noUnusedLocals flag detection within function* block

Compiler options: "noUnusedLocals": true, "noUnusedParameters": true, are not functioning properly within functions. An error is encountered in the following example: export class AllReduxSagas { [ts] Property 'someService' is declared bu ...

Encountering issues with MediaSession.setPositionState() and seekto functionalities not functioning properly

Having trouble with MediaSession.setPositionState() not displaying the audio time and seekbar not behaving as expected. const sound= document.querySelector('sound'); function updatePositionState() { if ('setPositionState' in navigato ...

Angular - issues with delete functionality

Recently, I implemented a delete button in my Angular program to remove a specific row from both the table and the database. However, despite feeling confident that my code should work flawlessly, it seems to be failing without any visible errors. Edit - ...

Failure to validate Google KMS asymmetric keys

Currently, I am in the process of developing an OAuth server implementation specifically tailored to meet custom requirements. In my endeavor, I decided to utilize Google's KMS service for the signing and verification of JWT tokens. While I managed t ...

Calculate the total of JSON objects while eliminating duplicates in an array

Below is an array of objects: const lineItems = [ { "lineNumber": "0", "item": "1496", "itemDesc": "wertyuiasdfghj", "qualityReceiptHold": "N", ...

Differences Between Public and Private Constructors in TypeScript

Is it correct to say that public members within a TypeScript constructor are accessible throughout the class, while private members are restricted? If this is true, what sets public members apart from properties? If properties can behave more like c# pro ...

Having trouble binding component property in VueJS with TypeScript?

Why is my component property not binding when I set the related component attribute to a value? Even when inspecting with Vue devtools or outputting the value into the HTML, it remains at the default value set on the component. I tried setting a string at ...

MSW is not effective when utilized in functions within certain contexts

Trying to intercept a post request using MSW for result mocking. A handleLogin function is located within a context, but MSW cannot recognize handleLogin as a function. An error occurs: ReferenceError: handleLogin is not a function. If the API call is made ...

How to preselect a value in a select tag in Angular 8

I am looking to assign a default value to a select tag, with the values being declared in a table within my component and displayed using the ngFor directive: <form> <div class="form-group col-4"> <span class="badge badge-theme m ...

I am facing issues with my filtering functionality on the Angular Typescript mat-table component

I am facing issues while trying to filter my table, the reaction is not correct and I can't seem to find where I went wrong. Here is the HTML part : <mat-form-field appearance="outline"> <mat-label>Search</mat-label> & ...

Tips for Implementing a Button Click Sound in Ionic 2

I've noticed that many native apps have a distinct click sound when buttons are pressed. Is there a way for me to add this same feature to all buttons in Ionic 2? ...

Encountering a new challenge in Angular: The error "InvalidPipeArgument: '' for pipe 'AsyncPipe'

Whenever I try to fetch data from the server, these errors keep popping up. This code was written by someone else and I would like to improve upon it. Could anyone suggest the best approach to handle this situation? Are there any coding patterns that sho ...

Uh oh! There seems to be an issue with the property 'getProjection', as it is undefined

I stumbled upon this post while facing a simple issue. However, I am looking to implement it in Typescript code. The code snippet for Android is as follows: googleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() { @Over ...

"Exploring the power of Angular 16 coupled with Firebase 9 for seamless file

Recently, I've been facing some challenges with my Angular 16 app that uses Firebase 9 and angular/fire 7. Specifically, I've been struggling to implement a simple file upload feature to Firebase storage. Despite spending the last couple of days ...

Issue with displaying Angular chart only resolves after resizing window following routing updates

Hey there! I'm having trouble getting my chart to show up after adding routing to my 3 tabs. Previously, without routing, everything worked fine. Now, the graph only appears after resizing the window. The chart is using PrimeNG chart with the Chart.js ...

Create a unique TypeScript constant to be mocked in each Jest test

Having difficulty mocking a constant with Jest on a per test basis. Currently, my mock is "static" and cannot be customized for each test individually. Code: // allowList.ts export const ALLOW_LIST = { '1234': true }; // listUtil.ts import { ...

Error message: Duplicate identifier found in Typescript

Encountering an error while trying to run my angular-meteor client (ionic serve), specifically: [00:29:20] typescript: node_modules/meteor-typings/1.3/main.d.ts, line: 657 Duplicate identifier 'Status'. L657: type Status ...

Guide on extracting the id from the path parameter in an HTTP request using Cloud Functions and nodejs

I am currently in the process of developing a serverless application using GCP Cloud Functions (nodejs). I have successfully implemented different behaviors based on the request method, but I am facing an issue with retrieving the id from the path paramete ...

Dealing with Angular Forms: Addressing the absence of a value accessor for

Seeking assistance with an AngularDart Material package issue. Can someone provide guidance on resolving this error message? "No value accessor for (username) or you may be missing formDirectives in your directives list." Here is the minimal setup wher ...