Creating and handling Observable of Observables in RxJS: Best practices

Within my Angular application, there are multiple services that have dependencies on each other. To manage this, I have created a dependency map as shown in the example below:

let accountInitialization$: Observable<void>;
let productInitialization$: Observable<void>;

const dependenciesMap = {
  accountService: [],
  productService: [
    accountInitialization$ // There could be one or more dependencies
  ]
}

accountInitialization$ = this.getDependencies(dependenciesMap.accountService)
  .pipe(
    mergeMap(_ => {
      return this.accountService.initialize();
    })
  );

productInitialization$ = this.getDependencies(dependenciesMap.productService)
  .pipe(
    mergeMap(_ => {
      return this.productService.initialize();
    })
  );

accountInitialization$.subscribe(() => {
  this.progressUpdate.next(StartUpProgressUpdate.AccountsInitialized);
});

productInitialization$.subscribe(() => {
  this.progressUpdate.next(StartUpProgressUpdate.ProductsInitialized);
});

forkJoin([accountInitialization$, productInitialization$]).subscribe(
  () => {
    // perform some actions after initialization
  },
  error => {
    console.log(error); // This is where errors are handled
  }
);

The Product Service relies on the initialization of the Account Service. The getDependencies function has the following structure:

private getDependencies(dependencies: Observable<void>[]) {
if (dependencies.length) {
  return forkJoin(dependencies);
}
return EMPTY;

}

In this scenario, the goal is to ensure that the Account Service initializes before the Product Service. However, an error message is being encountered:

ERROR TypeError: You provided 'undefined' where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.

It appears that the .initialize() functions are not being invoked...

If you have any insights on how to resolve this issue, your assistance would be greatly appreciated. Thank you.

Answer №1

Instead of using forkJoin, you should consider utilizing switchMap. The structure could be similar to the following example:

import { switchMap } from 'rxjs/operators';
...
productInitialization$ = this.accountInitialization$.pipe(
  switchMap(accountInitializtion => {
    console.log('account initialization finished with: ', accountInitialization);
    // switch to this observable once complete
    return this.productService.initialize();
  });
)

Your specific case may require a different approach, so explore options like concatMap, switchMap, mergeMap for transitioning between Observable streams.

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

Tips on showing validation error message through a tooltip when hovering over the error icon in Ionic

Currently, I have implemented bootstrap validation within my Ionic application and it is functioning correctly. The error icon appears within the textbox along with the error message below the textbox. However, I am interested in changing this setup so t ...

Is it feasible to integrate gMaps with Angular2? How can I go about accomplishing this task?

In developing a typeahead service for cities and similar functions, I require the use of a typeahead directive (ng2-bootstrap) with an array of strings provided by the service. Google Maps is my chosen solution for this task. Below is code extracted from ...

Angular progress tracker with stages

I have been exploring ways to create a progress bar with steps in Angular 12 that advances based on the percentage of progress rather than just moving directly from one step to another. This is specifically for displaying membership levels and indicating h ...

The Material Angular components fail to load

Just started a brand new project using Angular and Material design UPDATE : Check out the live editor on StackBlitz: here Working on implementing the toolbar example, but here's what I have so far: Tried inserting the sample code into the app.compo ...

Why is it necessary to use "new" with a Mongoose model in TypeScript?

I'm a bit confused here, but let me try to explain. When creating a new mongoose.model, I do it like this: let MyModel = moongoose.model<IMyModel>("myModel", MyModelSchema); What exactly is the difference between MyModel and let newModel = ne ...

The child component fails to inherit the data types provided by the parent component

I am currently working on setting up a dynamic table that will receive updates from the backend based on actions taken, which is why I need to pass the endpoint and response model. When I try to nest and pass the response type, it seems to get lost in the ...

I am experiencing some issues with the functionality of the Bootstrap carousel on my website's homepage

I've been working on creating an image carousel with Bootstrap 4, but I'm running into some issues. The images aren't sliding properly, and the cursor to change slides isn't functioning correctly. Additionally, the slides seem to repeat ...

Angular Router navigation not functioning as expected

I have successfully implemented routing in my Angular project. Below are the routes defined in the root module: const appRoutes: Routes = [ { path: '', component: LoginComponent }, { path: 'dashboard', canActivate: [AuthGuard], comp ...

What causes the discrepancy between the response.headers in Angular and the response headers shown in the browser's developer

this.http.post(this.url+"/login",formData).subscribe( (response: any)=>{ console.log(response.headers); const cookies = response.headers.get('Set-Cookie'); // console.log(response.headers); console.log(c ...

DuplicateModelError: Unable to duplicate model after it has been compiled, React.js, MongoDB, TypeScript

In the early stages of developing an application using Next.js, Mongoose, and Typescript, I encountered a persistent issue. Whenever I attempt to send a request through Postman after clicking save, it fails, displaying the error message: OverwriteModelErr ...

What could be causing a custom Angular library to fail to compile after being published on npm?

I recently launched a library that I created for my team to expedite the process of developing applications specifically for the Internet of Things (IOT) sector. However, I have encountered an issue where the library compiles without errors in the demo pro ...

Solutions for Utilizing Generic Mixins in Typescript

As a newcomer to Typescript, I have encountered an issue with mixins and generics. The problem became apparent when working on the following example: (Edit: I have incorporated Titian's answer into approach 2 and included setValue() to better showcas ...

Fix React/Typescript issue: Exported variable conflicts with name from external module

I am encountering a perplexing issue when using React with Redux and Typescript. The error message I am receiving is unfamiliar to me, and I am unsure how to resolve it. The error states: Exported variable 'rootReducer' has or is using name ...

Error TS2322: Cannot assign a variable of type 'number' to a variable of type 'string'

Encountered an issue with TS2322 error while attempting to compile my Angular application. The error occurs when using a variable [link] that represents the index number. When declaring this variable, I use: @Input() link!: string; This link is used as ...

Guide for setting up filtering and sorting on a multi-value array column with MUI's data grid

I've encountered an issue with the MUI Data Grid component's free version, specifically regarding filtering and sorting on a column that displays multiple values in an array. The problematic column in this case is 'tags', which showcase ...

Showing the AngularFireList data on the HTML page following successful retrieval

Does anyone know how to display an AngularFireList on an HTML page? import { Component } from '@angular/core'; import { NavController } from 'ionic-angular'; import {AngularFireAuth} from 'angularfire2/auth'; import {AngularF ...

Testing TaskEither from fp-ts using jest: A comprehensive guide

Entering the world of fp-ts, I encounter a function (path: string) => TaskEither<Erorr, T> that reads and parses configuration data. Now, my challenge is to create a test for this process. Here is what I have tried so far: test('Read config& ...

Obtain the Enum's Name in TypeScript as a String

I am currently looking for a solution to transform the name of an enum into a string format. Suppose I have the following Response enum, how can I obtain or convert 'Response' into a string? One of my functions accepts any enum as input and requi ...

Display the data in ngx-charts heat map

I have been utilizing ngx charts to display data in a Heat Map. The implementation is smooth without encountering any issues. View Working Example | Heat Map However, I am interested in displaying the values of each grid rather than just on mouse hover. ...

Testing React Hooks in TypeScript with Jest and @testing-library/react-hooks

I have a unique custom hook designed to manage the toggling of a product id using a boolean value and toggle function as returns. As I attempt to write a unit test for it following a non-typescripted example, I encountered type-mismatch errors that I' ...