Improve disorganized subscription processes to enhance future subscriptions

While diving into my Angular learning journey, I stumbled upon Observables which intrigue me but still hold a mystery for me. One specific challenge I faced was having an Observable that depended on another Observable to complete before proceeding.

This led me to nesting the observables to tackle some sequence issues arising from their independent nature. However, as I explored this approach further, it seemed to become a bit messy, and I anticipate needing to introduce more nested observables down the line.

Here's a snippet of the code illustrating my current structure...

    this.permissionService.build().subscribe( p =>{
        this.Headers = p; 
        this.accessService.buildTitlesWithMenus().subscribe( q => {
          this.treeNodes = this.accessService.buildTreeTable(q); 
        });                 
    });

Answer №1

this.authorizationService.create().pipe(
  tap(a => this.Headers = a),
  switchMap(a => this.menuService.generateMenus()),
).subscribe(m => this.treeNodes = this.menuService.buildTreeTable(m));

This method is recommended for handling the task at hand.

Don't hesitate to reach out if you have any queries!

Answer №2

Here is a traditional approach to structuring your code in a readable manner:

  1. Utilize the forkJoin method from rxjs

This method accepts an Array of ObservableInput or a dictionary Object of ObservableInput. It returns an Observable that emits either an array of values in the exact same order as the passed array, or a dictionary of values in the same shape as the passed dictionary.

private buildPermissionService() {
    return this.permissionService.build();
}

private buildTitlesWithMenus() {
    return this.accessService.buildTitlesWithMenus();
}

private buildMenuAndPermissions() {
    return forkJoin(
        this.buildPermissionService(),
        this.buildTitlesWithMenus()).subscribe(result => {
        this.Headers = result[0];
        this.treeNodes = this.accessService.buildTreeTable(result[1]);
    });
}
  1. Opt for the switchMap method provided by rxjs

This method projects each source value to an Observable which is merged in the output Observable, emitting values only from the most recently projected Observable.

this.permissionService.build().pipe(
  tap(p => this.Headers = p),
  switchMap(p => this.accessService.buildTitlesWithMenus()),
).subscribe(q => this.treeNodes = this.accessService.buildTreeTable(q));

There are more methods available in the documentation. For example, if you need to not only get the result but also combine it, you can consider using zip or combineAll.

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

Injecting AngularJS together with TypeScript and Restangular to optimize application performance

Encountering an issue while trying to configure my angularjs + typescript application with the restangular plugin Here are the steps I have taken: Ran bower install --save restangular (now I have in index.html <script src="bower_components/restang ...

Using typescript with Ramda's filter and prop functions can lead to unexpected errors

I'm new to TypeScript and currently facing the challenge of converting JavaScript functions that use Ramda library into TypeScript functions. The lack of clear TypeScript usage in the Ramda documentation is making this task quite difficult for me. Sp ...

Enforce directory organization and file naming conventions within a git repository by leveraging eslint

How can I enforce a specific naming structure for folders and subfolders? I not only want to control the styling of the names (kebab, camel), but also the actual names of the folders and files themselves. For example, consider the following paths: ./src/ ...

What could be causing issues when trying to update the profile picture effectively?

I have encountered an issue where every time I update a user's profile picture, it reverts back to the default image whenever the page is refreshed. This consistent behavior suggests that the new profile picture may not be saving correctly in the data ...

What is the definition of a non-arrow React functional component in TypeScript?

Defining types for a React functional component in TypeScript can be done like this: export const Component: React.FC = () => { return // Content }; But how would you define the types for a non-arrow function? function Component() { return // Con ...

Access a single document from Firestore:

How can I fetch a single document from Firestore in Angular 4? I am not looking for a list of documents in the collection, I already know how to do that. Let's say I have a key-value pair of the document and I want to retrieve it using Angular 4. i ...

Angular: How to Disable Checkbox

Within my table, there is a column that consists solely of checkboxes as values. Using a for loop, I have populated all values into the table. What I have accomplished so far is that when a checkbox is enabled, a message saying "hey" appears. However, if m ...

Can someone confirm if I am importing this png file correctly? I am encountering an error with Vite, here is my code

Error: TypeScript+ React + Vite [plugin:vite:import-analysis] Failed to find import "./assets/heropic.png" in "src\components\Hero.tsx". Are you sure the file exists? Hello fellow developers! I am new to working with react and typescript. Curren ...

Slow initialization of the Angular APP_INITIALIZER for the application's configuration

Working with Angular 8 and my AppModule is configured as follows: { provide: APP_INITIALIZER, useFactory: initConfig, deps: [AppConfigService], multi: true, } The factory function looks like this: export function initConfig(appConfig: AppConfigService) { ...

Finding the key type in an interface

Here is a challenge... This is the code snippet from titleBarContainer.tsx: function TitleBarContainer() { const systemData = useSelector((state: RootState) => state.counter.systemData) const dispatch = useDispatch() const onChangeSystemDa ...

Oops! We encountered an issue when trying to set the property 'isAdmin' to null

When the user's authentication state changes, the following code is executed: firebase.auth().onAuthStateChanged((user) => { if(user) { this.isLoggedIn = true; //Flag user as logged in this.isAdmin = false; //Initialize isAdmin flag to f ...

Utilize the MD_CARD component exclusively from Material Design 2, omitting the rest of the features from the Material

Is it possible to selectively use certain material design components without having to include the entire library? I am particularly interested in utilizing MD_CARD_DIRECTIVES. ...

"Trouble accessing the URL" error encountered when trying to load templateUrl for dynamic components in Angular 2

Attempted to modify a solution found here. The modification works well, but when changing the template to templateUrl in the component that needs to be loaded dynamically, an error occurs: "No ResourceLoader implementation has been provided. Can't rea ...

When the component is initialized, the mat-autocomplete input element displays a [object object]

HTML: <form [formGroup]="basicForm"> <section> <mat-form-field> <mat-label>Select Country*</mat-label> <input matInput type="text" maxlength="20" formCon ...

Ending the Infinite Scroll in Ionic 3 When Data Runs Out

I am having an issue with my json data where I need to figure out how to stop the infinite scroll once there is no more data available. Can anyone help me implement this feature? Below is the code snippet for reference: handleDataLoad(currentCount) ...

Is it possible to establish a connection between Firebase Storage and HTML using TypeScript without Angular or React in IntelliJ?

My project goal is to create a functional login and register page using TypeScript. Currently, my code operates without a database, but I aim to implement Firebase for registering user credentials for easy login. I have only come across tutorials using F ...

How Angular services transmit information to components

I have implemented a search field within my top-bar component and I am facing an issue in passing the input value of that search field to another component. Design Search service Top bar component Result component Operation Top bar component receives th ...

Upgrading $compile in Angular

In my pursuit to compile HTML content in Angular 4, I have come across options like $compile in Angular 1. Unfortunately, the suggested alternatives in Angular 2 are now outdated. If anyone has a better approach, please advise me on the most effective wa ...

Using TypeScript to access the value of the parent scope within a directive controller

I am facing an issue with my directive. export class SigninFormDirective implements angular.IDirective { // setting up the directive restrict: string = 'AE'; templateUrl: string = "/public/app/signin/views/directiveTemp ...

Issue with Undefined Variable in Angular 2 and Ionic Framework

I included the following code in my HTML file: <ion-col col-3 align="right"> <ion-item> <ion-label>Show as</ion-label> <ion-select [ngModel]="SelectedView" (ngModelChange)="onViewChange($eve ...