Running RXJS Functions in a Sequence Maintained by an Array

I am trying to run a series of functions in sequence by storing them in an array (specifically for an Angular APP_INITIALIZER function).

Here is the array in question:

const obsArray = [
    myService1.init(),
    myService2.init(),
    ...
    myServiceN.init()
]

Each of these init() functions returns an Observable<void>. Here's an example:

    init() : Observable<void> {
         return this.http.get(this.apiUrl)
             .pipe(
                 // do something with the response
                 switchMap(() => EMPTY)
             );
    }

The switchMap statement ensures that the return type is Observable.

I've attempted this approach:

    const init$ : Observable<void> = forkJoin(obsArray);

However, it seems to execute the function but not the HTTP call within. Since this is within an Angular factory function assigned to the APP_INITIALIZER token, there is no subscribe() call.

I've also tried using concatMap() without success.

Is there an rxjs function that can run each of these functions sequentially, waiting for the previous one to complete?

I have posted a related question on Stack Overflow.

Answer №1

Another approach is to gather all observables from the array into a single observable, essentially transforming Array<Observable<T>> into

Observable<Observable<T>>
and then utilizing the higher order function concatAll:

from(obsArray).pipe(concatAll())

Check out this interactive demo.

Answer №2

It seems that the issue lies in the fact that the sources provided to forkJoin are not emitting anything. As stated in the documentation:

Whenever any of the given observables completes without emitting any value, forkJoin will also complete at that moment without emitting anything

By utilizing switchMap(() => EMPTY), you end up with an Observable<never> type. To ensure that your init methods return Observable<void>, you can make use of map(() => undefined) instead:

init(): Observable<void> {
    return this.http.get(this.apiUrl).pipe(
        map(() => undefined)
    );
}

This adjustment will ensure that the forkJoin receives emissions from each source and functions as expected.

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

Refresh the webpage following removal of an item on IONIC4

Hey there, I need some help from the experts here. I'm currently working on developing an e-commerce mobile app using Ionic 4. I'm facing a challenge with updating the item-total summary when an item is removed from the cart page. Below is my ca ...

Setting various colors for different plots within a single chart: A step-by-step guide

I'm currently tackling a project that requires me to showcase two different plots on the same chart, one being a "SPLINE" and the other a "COLUMN". My aim is to assign distinct background colors to each of these plots. Please note that I am referring ...

Identifying the camera model using getMediaStream

Are there methods available to determine if a user's device has a front, rear, or dual cameras installed? For instance, laptops typically only have a front-facing camera while some devices may have both. I am looking for a way to identify the type of ...

Maintain query parameters in Angular6 while routing with canActivate

When using Auth guard to verify login status and redirecting to the login page if a user is not logged in, there seems to be an issue with losing all query parameters during the redirection process. I attempted to preserve the query params by adding { qu ...

What is the best way to extract multiple records from an Array?

Below is a simple filter function that filters Rec_pagedItems in an array called allItems. someval(value){ if(value.length>=5){ this._pagedItems= this.allItems.find(e=>e.uniqueid == value || e.name == value ); if(this._pagedItem ...

merging JavaScript objects with complex conditions

I am attempting to combine data from two http requests into a single object based on specific conditions. Take a look at the following objects: vehicles: [ { vId: 1, color: 'green', passengers: [ { name: 'Joe', ag ...

Angular 12: Running ng test shows code coverage error - TypeError: Unable to access 'initialize' property as undefined

I encountered an error in the code coverage console: TypeError: Cannot read properties of undefined (reading 'initialize') I am trying to call a service method from the component.ts file The code in the component.ts file looks like: this.myAuth ...

What is the process of using observables in Angular to retrieve a number or variable?

While working on an angular service that calls an API and processes a large amount of data, I encountered an issue. I was trying to count the occurrences of each type in the data and send back that count along with the data itself. However, I found that wh ...

Issues with slider functionality in a Next.js application styled with Tailwind CSS

"use client"; import React, { useState } from "react"; const textData = [ { id: 1, text: "Text 1 Description", }, { id: 2, text: "Text 2 Description", }, { id: 3, text: "Text 3 ...

Verifying the checkbox status based on the loop value in Angular

In my Angular app, I am struggling to set a checkbox as checked based on a loop value in the template. Can anyone provide guidance or assistance? Thank you in advance for your help. Expected Result: http://prntscr.com/obcgic Here is my response: http:/ ...

What could be causing the error in Angular 2 when using multiple conditions with ng-if?

My aim is to validate if the length of events is 0 and the length of the term is greater than 2 using the code below: <li class="more-result" *ngIf="events?.length == 0 && term.value.length > 2"> <span class="tab-content- ...

Display items according to the visible element

Just starting with Angular and could use some guidance In my header component, I have a bootstrap navbar consisting of ul and li elements along with a router outlet. <app-header></app-header> <router-outlet></router-outlet> I&apo ...

There was an issue encountered while compiling the template for 'AppModule'

While attempting to construct an Angular 6 application, I encountered an issue when utilizing the --prod flag. ERROR in Error during template compile of 'AppModule' Expression form not supported in 'reducers' 'reducers' ...

Retrieve user roles from OpenID Connect client

Utilizing oidc-client for authentication in my application with Angular and ASP.NET Core 3.1. Is there a way to retrieve the user roles from ASP.NET using oidc client? ...

The call stack size has been exceeded in Next.js, resulting in a RangeError

Currently attempting to deploy my project on vercel.com but encountering an error specifically with 3 pages that have no internal errors. An error occurred while prerendering the page "/applications". For more information, visit: https://nextjs.org/docs/me ...

Declaration of types for invoking the lodash `mapKeys` function

Is there a way to create a function that can map object keys from camelCase to snakeCase, and be used multiple times with different objects? I have already written a function called mapKeysToSnakeCase which does the job, but I'm curious if there is a ...

Creating a loader for a specific component in Angular based on the view

Creating a loader for each component view is crucial when loading data from an API. Here is the current structure of my components within my <app-main></app-main>: <app-banner></app-banner> <app-data></app-data> <app ...

What type should React Router props be?

For a specific scenario, I developed a custom router component that redirects if certain parameters are missing: const StateParamRoute = (props: any) => { ... return stateParam ? <Route {...props} /> : <Redirect to="/error" />; ...

Updating the state in React Native does not occur

I'm facing an issue where I can't seem to update the state using useState while coding in React Native. The component in question is a styled TextInput named SearchField. Can anyone help me figure out what I might be doing wrong that's preve ...

Encountering an error in testing with Typescript, Express, Mocha, and Chai

After successfully creating my first server using Express in TypeScript, I decided to test the routes in the app. import app from './Server' const server = app.listen(8080, '0.0.0.0', () => { console.log("Server is listening on ...