The most effective approach to creating linked observable subscriptions

How can we refactor this code reactively using RxJS for better performance?

let profileInformation;
updateProfile() {
let token;
let profileId = 1;
this.userService.getAccessToken()
    .pipe(
        tap((res) => {
            //as I need it multiple times
            token = res;
        }),
        switchMap(accessToken => this.profleService.getContactIds(accessToken, profileId)),
        switchMap(res => this.profleService.updateprofile(token, this.profileInformation, res.account.id, res.address.id)),
    )
    .subscribe(data => {
        console.log(data);
        //do stuff with data
    }, err => {
        //handle error
    });
}

Answer №1


function updateProfile() {
  let userToken;
  const profileId = 1;

  this.userService.getAccessToken()
    .do(accessToken => userToken = accessToken)
    .switchMap(accessToken => this.profleService.getContactIds(accessToken, profileId))
    .flatMap(({account, address}) => this.profleService.updateprofile(userToken, this.profileInformation, account.id, address.id))
    .subscribe(response => {
      console.log(response);
      // Perform actions with response data
    }, error => {
      // Handle the error here
    });
}

Choosing to use flatMap instead of a nested switchMap has its advantages. In this context, switchMap spreads the first observable that emits a value. By using flatMap (also known as mergeMap), we maintain the original behavior by processing all emitted values without nesting.

Although using flatMap may not make a difference if only one value is emitted, the true power lies in its ability to handle multiple emitted values, preserving the observables' semantics while enhancing readability.


For those interested in the syntax of the projection function within flatMap:


({account, address}) => 
  this.profleService.updateprofile(userToken, this.profileInformation, account.id, address.id)

This syntax demonstrates ES2015 parameter destructuring, which simplifies extracting properties from parameters into local variables. Since account and address were consistently accessed, it is presumed that they are properties of the original res. This technique is commonly used in callbacks and projection functions.

For instance:


interface Entity {
  id: number;
}

declare const entities: Entity[];

function getById(entityId: number) {
  return entities.find(({id}) => id === entityId);
}

Answer №2

If you need to use switchMap again

this.authenticationService.retrieveToken()
  .do(tokenValue => token = tokenValue)
  .switchMap(token => this.userService.getUserDetails(token, userId))
  .switchMap(details => this.userService.updateUser(token, userDetails, details.account.id, details.address.id))
  .subscribe(
    (response) => {
      console.log(response)
    }, (error) => {
    });

Answer №3

After reviewing various responses, I decided to merge the most helpful aspects of answers from @juliapassynkova and @aluanhaddad

profileInformation;
updateProfile() {
    let token;
    let profileId = 1;
    this.userService.getAccessToken()
        //for multiple using token
        .do(accessToken => token = accessToken)
        .switchMap(accessToken => this.profleService.getContactIds(accessToken, profileId))
        .switchMap(res => this.profleService.updateprofile(token, this.profileInformation, res.account.id, res.address.id))
        .subscribe((data) => {
            console.log(data);
            //do stuff with data
        }, (err) => {
            //do something when err
        })
}

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

Where is the best place to obtain the clientSecret key for mounting Stripe elements?

UPDATED CODE Hello, I am looking to integrate Stripe for user subscriptions. I'm unsure about the client Secret key in my setup. I am using Ionic 5 with Angular 14 and Capacitor 5, along with PHP as the backend. In my implementation, I used PHP to ...

Exploring Typescript: Enhancing the functionality of `export = Joi.Root`

I've noticed that the types for @hapi/joi appear to be outdated - some configuration parameters mentioned in the official documentation are missing from the types. To address this, I am attempting to enhance the existing types. node_modules/@types/ha ...

Hapi and Bell's attempt at authenticating with Twitter was unsuccessful

Currently, I have developed a basic backend API that requires multiple authentications. My current challenge is connecting to the Twitter API using Bell. However, instead of displaying the authentication page for the app, an error is being shown: {"statusC ...

Angular2 Component: Evaluating the modification of the input value in a form

I'm currently working with a text input and monitoring for any changes that occur. mycomponent.ts ngOnInit() { this.searchInput = new Control(); this.searchInput.valueChanges .distinctUntilChanged() .subscribe(newValue => ...

What could be causing the lack of reflection of Angular changes in the browser post-build process?

I'm having trouble seeing changes reflected in my Angular project after making them. I've tried clearing the cache pages and cookies in Chrome, as well as enabling disable cache in the network tab of developer tools. In addition, I cleared the a ...

"Twice the charm: Angular routing resolver runs not once

Having an angular 10 application with a routing resolver added to one of its components. Upon navigating to the resolver-added component through a different service, it has been noticed that the routing resolver is being called twice for each request. The ...

Angular refusing to refresh specific section of the UI

In my component, I am displaying charts and a table showing the latest values for each chart. This is done for each object in an array, as shown below: <div class="patient-box level-2" *ngFor="let bed of patientService.bedsLevel2" draggable="true" (dra ...

Guide on defining a data type for the response payload in a Next.js route controller

interface DefaultResponse<T> { success: boolean; message?: string; user?: T; } export async function POST(req: Request) { const body: Pick<User, 'email' | 'password'> = await req.json(); const user = await prisma ...

Incorporating HTML and JavaScript into TypeScript: How to Embed a Shopify Buy Button in a .tsx document

I am currently looking to integrate Shopify with my personal website. My frontend is built using React (NextJS with TypeScript). The embed code for the Shopify buy button consists of an HTML div tag wrapping JavaScript. I am wondering how I can effectivel ...

Challenges arise when attempting to break down an API into separate components rather than consolidating it into a

I've been struggling with this issue for a few days now. Problem Explanation: I am trying to use Axios to fetch data and store it in the state for each individual Pokémon. However, currently all the data is being rendered inside a single component w ...

Discovering the bottom scroll position in an Angular application

I am working on implementing two buttons on an Angular web page that allow the user to quickly scroll to the top and bottom of the page. However, I want to address a scenario where if the user is already at the very top of the page, the "move up" button sh ...

ngx-emoji-mart customBackgroundImage directive

Currently, I am integrating ngx-emoji-mart with Angular 6 and encountering an issue with the backgroundImageFn directive. The ngx-emoji-mart documentation suggests using the directive to load the emoji sheet locally like this: <emoji-mart [backgroundIm ...

What is the implementation of booleans within the Promise.all() function?

I am looking to implement a functionality like the following: statusReady: boolean = false; jobsReady: boolean = false; ready() { return Promise.all([statusReady, jobsReady]); } ...with the goal of being able to do this later on: this.ready().then(() ...

AmplifyJS is throwing an error: TypeError - It seems like the property 'state' is undefined and cannot be read

I am currently working on integrating the steps outlined in the Amplify walkthrough with an Angular cli application. My app is a brand new Angular cli project following the mentioned guide. My objective is to utilize the standalone auth components a ...

Angular Material 2: Sidenav does not come with a backdrop

I'm encountering an issue with the SideNav component while developing a website using Angular 2. The SideNav has 3 modes, none of which seem to affect what happens when I open it. I am trying to make the backdrop display after opening. Even though t ...

Tips for retrieving a server-set cookie in your Angular 2 application, and guidelines for including the same cookie in requests made by your Angular 2 application

Requirement: Our application should be able to support the same user opening our web application as a separate session. The issue is not about how to use cookies in Angular 2, but rather how the server can retrieve cookies from the HTTPServletRequest obje ...

The mat-checkbox is failing to accurately reflect its checked state

This code snippet is from my .html file: <mat-checkbox [checked]="getState()" (change)="toggleState()">Example Checkbox</mat-checkbox> <br><br> <button mat-raised-button color="primary" (click)=" ...

The key to subscribing only once to an element from AsyncSubject in the consumer pattern

When working with rxjs5, I encountered a situation where I needed to subscribe to an AsyncSubject multiple times, but only one subscriber should be able to receive the next() event. Any additional subscribers (if still active) should automatically receive ...

Utilizing Express-sessions to generate a fresh session with each new request

I'm facing an issue with my express backend using express-sessions and Angular frontend. Every time the frontend makes a request, a new session is created by express-sessions. I suspect the problem lies in Angular not sending the cookie back, as I don ...

Issue encountered when attempting to run "ng test" in Angular (TypeScript) | Karma/Jasmine reports an AssertionError stating that Compilation cannot be undefined

My development setup includes Angular with TypeScript. Angular version: 15.1.0 Node version: 19.7.0 npm version: 9.5.1 However, I encountered an issue while running ng test: The error message displayed was as follows: ⠙ Generating browser application ...