Sequencing API Calls: A Guide on Making Sequential API Requests

Currently, I am working on mastering RxJS. Within my project, there are 3 API calls that need to be made. Specifically, I must execute the 2nd API call and then pass its data as a parameter to the 3rd API call. My attempt at achieving this functionality is outlined below:

    checkPermission(permissionName: string): Observable<boolean> {
    this.check(this.p1)
      .pipe(
        switchMap(res => {
          const shouldCheck = res.Value;
          if (shouldCheck.toLowerCase() === 'true') {
            return this.checkPermission(permissionName).pipe(
              map(result => {
               
                return result;
              })
            );
          } else return of(true);
        })
      )
      .subscribe(permission => {
       
      });       
    }

Unfortunately, I encountered a syntax error while testing this implementation.

Answer №1

The code snippet you provided may be a bit hard to follow, but I will attempt to improve its readability:

  validatePermission(permissionName: string): Observable<boolean> {
    return this.checkSetting(this.p1).pipe(
      map((res) => res.SysConfig.Value.toLowerCase() === 'true'),
      switchMap((shouldValidate) =>
        iif(
          () => shouldValidate,
          this.checkAuthorization(this.p2).pipe(
            switchMap((data) =>
              this.validatePermissionStatus(permissionName, data.SysConfig.Value)
            ),
            // assuming that the authorization status is boolean
            map((res) => res.authorized)
          ),
          of(true)
        )
      )
    );
  }

If you intend on returning an Observable<boolean>, it's recommended to avoid using subscribe within this method. You can subscribe to the observable at the point of usage like so:

this.authService.validatePermission(accessControl).subscribe(hasAccess => {
  console.log(`User ${hasAccess ? 'has' : 'does not have'} access control for ${permission}`);
});

Answer №2

Feel free to give this a shot, I haven't personally verified it.

   verifyPermission(permission: string): Observable<boolean> {
      return this.verifyCompanySettingForPermission(this.p1)
          .pipe(
            switchMap(result => this.checkUserPermissionAPI(result, permission)),
            tap(perm => this.$permissionSub.next(perm)),
            switchMap(_=> this.$permissionSub.asObservable())
          )
     }
    
    checkUserPermissionAPI(result :any, permission: string): Observable<any>{
        const shouldVerify = result.SysConfig.Value;
        if (shouldVerify.toLowerCase() === 'true') {
           return this.processUserPermissionAPI(permission);
        }
        return of(true);
    }

  processUserPermissionAPI(permission: string) :Observable<boolean>{
    return this.verifyCompanySettingForPermission(this.p2).pipe(
       switchMap(data => 
        this.validatePermission(permission, data.SysConfig.Value).pipe(
              map(( {granted})=>granted)
            )
        )
     );
  }

Answer №3

To optimize your code, make sure to utilize the switchMap operator in the correct sequence:

.pipe(
    switchMap(() => {
        return this.someFunctionThatReturnsObservable();
    }),
    // By doing this, you can access the data returned in the previous step through the 'data' variable
    switchMap((data) => {
        return this.someOtherRequest(data.param1, data.param2).pipe(
            map(result => {
              return result.permission;
            })
        );
    })
)

It is important to remember that when using rxjs operators, they should be placed one after another within the pipe separated by commas. The issue lies in attempting to insert code without the appropriate operators within the pipe. These lines are causing a problem:

return this.permission(this.p2).pipe(
    const shouldEncrypt = res.SysConfig.Value;

The intention behind this section is not entirely clear, but it seems like there is an attempt to conditionally return a request or an empty observable. To achieve this, ensure that you include the necessary operator before inserting the code mentioned above.

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 steps can be taken to establish an array type that is limited to predefined values?

I am currently working on defining a type for an array that requires specific values to be present in a certain order at the beginning of the array. type SpecificArray = ('hello'|'goodbye'|string)[] // Current const myArray: SpecificAr ...

Completing a fetch promise and sending the outcome to a function that is not awaited

I have a function that retrieves data from a Postgresql database and returns it. The expected behavior is to fetch the data using the async function getCat(), process it in const Catalogue, and then return it to a ReactJS component. catalogue.tsx: import ...

The limitations of Typescript types influence the program's behavior

As a newcomer to the Typescript environment, I am currently developing a test application to familiarize myself with it. However, I have encountered an issue regarding type restrictions that seems to be not working as expected. In my class, I have defined ...

Is it possible to specify the data type of form control values when using the Angular Reactive form builder?

Is it possible to use typed reactive forms with Angular form builder? I want to set the TValue on the form control to ensure we have the correct type. For example: public myForm= this.fb.group({ name: ['', [Validators.required, Validators.max ...

I am currently working on developing a web application for a class assignment and I am unsure whether I should opt for PHP7 Non Thread Safe or Thread Safe version

While I consider myself a beginner in the realm of programming, my knowledge is limited to Python. However, I am eager to explore using PHP7+ and Typescript with Angular 2+. I've come across recommendations for these languages online, but I'm uns ...

Distributing utility functions universally throughout the entire React application

Is there a way to create global functions in React that can be imported into one file and shared across all pages? Currently, I have to import helper.tsx into each individual file where I want to use them. For example, the helper.tsx file exports functio ...

Leverage TypeScript for modifying local node package alterations

As a newcomer to npm and TypeScript, I may be overlooking something obvious. Our team has developed a node package in TypeScript for internal use, resulting in the following file structure: src/myModule.ts myModule.ts The contents of myModule.ts are as f ...

Converting an array of arguments into tuples within the range of <T extends Tuple> is denoted by [T, (...args: NonNullArray<T>) => any], where each tuple represents the argument of a

Let's start with a simple function that takes a tuple as its first argument and a function whose arguments are elements of the tuple that are not null as its second argument: let first: number | null | undefined; let last: number | null | undefined; l ...

Retrieve the value of an HTML attribute from a nested element with Angular 2

I've created an Angular 2 accordion header component that stores its collapsed state in the class attribute of the root element. Within this component, there is a chevron glyphicon that I would like to toggle between two different icons based on the ...

Element not recognized: <my-company-form-extra> - have you properly registered this component?

I've been attempting to render a component using the is directive <template> <div> <v-tabs v-model="currentTab" fixed-tabs> <v-tab v-for="(item, i) in tabItems" :key="i">{{ item }} < ...

Angular4 - Streamlined error tracking and management for all HTTP requests

I have created a customized wrapper class for handling all my http requests. The example provided only includes the get function: import { Injectable } from '@angular/core'; import { HttpClient, HttpParams, HttpResponse, HttpHeaders } from &apos ...

What is the best way to integrate environment-specific configuration options into an AngularJS and Typescript project?

Currently, I am working on a project using AngularJS, Typescript, and VisualStudio. One of the key requirements for this project is to have a configuration file containing constants that control various settings such as REST API URLs and environment names. ...

Creating multiple dynamic dashboards using Angular 4 after user authentication

Is there a way to display a specific dashboard based on the user logged in, using Angular 4? For example: when USER1 logs in, I want dashboard 1 to be visible while hiding the others. Any help would be greatly appreciated... ...

Ways to invoke a function in HTML aside from using the (click)="function()" syntax

How can I display data from a GET request to the WordPress API as the page loads in an Ionic app using Angular? I am able to retrieve my desired post list, but only when I use a button click event to call the method in the HTML. Since this is my first att ...

Alert me in TypeScript whenever a method reference is detected

When passing a function reference as a parameter to another function and then calling it elsewhere, the context of "this" gets lost. To avoid this issue, I have to convert the method into an arrow function. Here's an example to illustrate: class Mees ...

Issue with Angular 8: Unable to access property 'database' of undefined when using @firebase

Recently, I decided to upgrade my configuration from angularfire2 v4 to @angular/fire v5.2.1 and firebase from v4 to v6.2.4. Unfortunately, during this process, I encountered an issue that caused the console to log the following error message: TypeError: ...

Using an aria-label attribute on an <option> tag within a dropdown menu may result in a DAP violation

Currently, I am conducting accessibility testing for an Angular project at my workplace. Our team relies on the JAWS screen reader and a helpful plugin that detects UI issues and highlights them as violations. Unfortunately, I've come across an issue ...

Challenges with Spreading Props in TextField Component After MUIv4 Upgrade with TypeScript

Latest Material-UI Version: 4.1.0 I'm encountering difficulties in passing props to an abstracted <TextField /> component that I've developed. Below is the snippet of code: PasswordInput.tsx import * as React from 'react' impo ...

Generating an array of keys from duplicated values in Typescript

My data is structured in the following array format: { itemTitle: 'value example', itemType: 'value example', itemDescription: 'value example', itemFamily: 'Asset', }, { itemTitle: 'val ...

What is the return type of the Array.prototype.sort() method in Typescript?

I have created a custom type for arrays that are considered "sorted" like this: type Sorted<T> = T[]; This serves as a reminder for developers to provide a sorted array of any type and ensure the sorting themselves. Although I understand that Types ...