Exploring Angular 12: utilizing rxjs observables with chained subscriptions for enhanced functionality and robust error handling

Can someone help me with creating a function that I can subscribe to, returning:

  • an observable containing the result if all operations were successful
  • an observable with an empty string in all other scenarios
  foo(): void {
      this.uploadImage.subscribe(res => console.log('url: ' + res));
  }

  uploadImage(): Observable<string> {
    if (isValid(this.file)) {
      this.httpHandler.uploadImage(this.file).subscribe(
        (result) => {
          if (result) {
            this.httpHandler.verifyUpload(result.uploadId).subscribe(
              (res) => {
              if (res) {
                return of(res.url);
              } else {
                return of('');
              }
            });
          } else {
            return of('');
          }
        }
      );
    } else {
      return of('');
    }
  }

  • I am struggling with adding a proper return statement at the end
  • In cases of error, nothing is being returned
  • The code feels cluttered, I simply want to return an Observable with an empty string if something goes wrong during the operation

Thank you for your assistance

Edit: updated version based on feedback - now working correctly:

    foo(): void {
        this.uploadImage().subscribe(res => console.log('url: ' + res));
    }
    
    uploadImage(): Observable<string> {
        if (isValid(this.file)) {
             return of(''):
        }
    
        return this.httpHandler.uploadImage(this.file).pipe(
          switchMap(result => {
            if (result) {
              return this.httpHandler.verifyUpload(result.uploadId)
            } else {
              return of('');
            }
          }),
          map((res: any) => res.verified?.url || ''),
          catchError(() => of(''))
        );
    }

Answer №1

If you want to accomplish this task, you can utilize the combination of switchMap and map operators in the following way:

bar(): void {
  this.uploadFile().subscribe(response => console.log('download link: ' + response));
}

uploadFile(): Observable<string> {
  if (checkValidity(this.file)) {
    return this.apiService.uploadFile(this.file).pipe(
      switchMap(result => {
        if (result) {
          return this.apiService
            .verifyUploadResult(result.identifier)
            .pipe(map(reply => reply?.link || ''));
        } else return of('');
      })
    );
  } else {
    return of('');
  }
}

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

Angular-12 ngx-datatable does not recognize the element 'ngx-caption' in Angular

Within my Angular-12 project, I have set up two modules: AppModule and AdminModule. Specifically, I am utilizing the following module for datatable functionality: "@swimlane/ngx-datatable": "^19.0.0", Here is how it is implemented in ...

Using Jest and Supertest for mocking in a Typescript environment

I've been working on a mock test case using Jest in TypeScript, attempting to mock API calls with supertest. However, I'm having trouble retrieving a mocked response when using Axios in the login function. Despite trying to mock the Axios call, I ...

Setting up types for variables in Angular 2 componentsHere is an

I have a model that consists of multiple properties, and I aim to set all these properties with a default value of either empty or null. Here is an example of my Model: export class MyModel { name: string; jerseyNumber: number; etc... } In m ...

Retrieving the text value of a selected option with a reactive form

This is my select option HTML <select _ngcontent-c3="" formcontrolname="role" value="" ng-reflect-name="role"> <option _ngcontent-c3="" value="addrole" ng-reflect-value="addrole">--Add Role--</option> <option _ngcontent-c3="" v ...

Is it possible to share screens via socket.io without the need for selecting a screen prompt?

I am looking to select my screen and share it on a socket.io server without any pop-up form the browser using navigator.mediaDevices.getDisplayMedia({ video: true }).then((stream: MediaStream) => { ...

Creating a web application using Aframe and NextJs with typescript without the use of tags

I'm still trying to wrap my head around Aframe. I managed to load it, but I'm having trouble using the tags I want, such as and I can't figure out how to load a model with an Entity or make it animate. Something must be off in my approach. ...

What is the process for retrieving the GitHub username in the GitHub OAuth Next.js sign-in callback in order to store it in a database?

1. Detail the issue I am facing a challenge while developing a Full Stack Website using Next.js and Typescript. Specifically, I am having difficulty persisting the Github Username in the database when a user signs in via Github OAuth. Should I consider st ...

How to dynamically customize styling on md-tab in Angular2-material?

Styling material design components can be challenging, especially when trying to dynamically set styles on an md-tab based on its active or archived state. I'm looking to make the tab header text italic and change its color to indicate whether it is a ...

Accessing the value of a FormControl in HTML代码

Modifying the value of a form select element programmatically presents an issue. Even after changing the value in the form, the paragraph element "p" remains hidden. However, if you manually adjust the form's value, the visibility of the "p" element ...

Troubleshooting Vue and Typescript: Understanding why my computed property is not refreshing the view

I'm struggling to understand why my computed property isn't updating the view as expected. The computed property is meant to calculate the total price of my items by combining their individual prices, but it's only showing me the initial pri ...

The back-end is not receiving the HTTP Get call, even though the URL is functional in the browser. The error message states that the JSON is

The backend function is functioning properly as both Postman and Swagger are able to call it without any issues. I decided to capture the URL string displayed in the error message and pasted it into a browser. Surprisingly, it successfully reached the bac ...

Tips for adjusting the dimensions of material table within a react application

Could someone please provide guidance on adjusting the size of a table made with material table? I am currently working in React and the following code is not yielding the desired outcome. I even attempted to use 'react-virtualized-auto-sizer' wi ...

Troubleshooting Angular 8 Child Routes malfunctioning within a component

I've encountered a peculiar issue – I've cloned ngx-admin and am attempting to utilize the theme as a base theme. I've crafted Layout Components with Modules featuring enabled Routing. The routes function without any hitches when accessed ...

The absence of the Angular property has been detected

Let's say you have the following model in your application. export class Instructor{ firstname:string; lastname:string; } export class Course { ID: number; title: string; crn: string; instructor:Instructor; } In order to reset a form, you can us ...

What is the best way to access the vue3datepicker object in order to manually close the date picker popup user interface?

Enhancement After yoduh's feedback, I made adjustments to the code below. However, vue3datepicker is still undefined. Code has been updated according to yodubs suggestion. I consulted the official vue3datepicker documentation to customize my own Act ...

Trying out the MatDialogRef overlayref: A step-by-step guide

What is the best way to test dialogref coming from MatDialogRef? dialogRef: MatDialogRef<testComponent>; displayBackdrop() { const backdrop = this.dialogRef['_ref'].overlayRef._backdropElement.style.display = 'block' ...

Deducting days, hours, and more from the current time using Angular 2

I am attempting to calculate the difference in days, hours, and minutes from the current time. Following the instructions on npmjs website, I have successfully installed the necessary package using the command: npm install --save add-subtract-date. Next, ...

Encountering a compilation error while trying to utilize a union type in a function parameter within an

As stated on https://www.typescriptlang.org/docs/handbook/declaration-files/do-s-and-don-ts.html, it is recommended to utilize multiple types for a parameter in a function (refer to the union part) /* OK */ interface Moment { utcOffset(): number; ...

Updating the variable value within the Highcharts selection event using Angular

Here is an angular 7+ code snippet using the Highcharts API: export class TestComponent implements OnInit{ seek: boolean = false; exampleChart; public options = { chart:{ zoomType: 'x', events: { ...

Guide on running PHP (WAMP Server) and Angular 2 (Typescript with Node.js) concurrently on a local PC

My goal is to create a Web app utilizing PHP as the server-side language and Angular 2 as the MVC framework. While researching Angular 2, I discovered that it is best practice to install Node.js and npm first since Angular 2 utilizes Typescript. Despite ha ...