Series of Observables producing identical Observable on completion

I am interested in implementing this functionality using rxjs:

  • I need to make a series of http calls;
  • I want these calls to be executed sequentially;
  • I want to transform the result of each call into an Observable stream of InfoMessage;

Pseudo-code that is not working as intended:

class InfoMessage {
  constructor(public message: string) {}
}

doAllRequests() : Observable<InfoMessage> {
    return Observable.create((obs: Observer<InfoMessage>) => {
      doRequest("http://test1.com").map((res: RxRequestResponse) => obs.next(new InfoMessage("request1 done")));
      doRequest("http://test2.com").map((res: RxRequestResponse) => obs.next(new InfoMessage("request2")));
      doRequest("http://test3.com").map((res: RxRequestResponse) => obs.next(new InfoMessage("request3")));
      obs.complete();
    });
  }

doRequest(url: string) : Observable<RxRequestResponse> {
  // utilizing an http client wrapped in an Observable of type RxRequestResponse
}

doAllRequests().subscribe(next => console("Message: " + next.message));

Update: recommended approach by Martin: Your solution appears to work, but only if I subscribe to the initial request like this:

Observable.create((observer: Observer<InfoMessage>) => {
  doRequest("http://test1.com")
    .do(response => observer.next(new InfoMessage("request1 done")))
    .concatMap(() => doRequest("http://test2.com"))
    .do(response => observer.next(new InfoMessage("request2")))
    .concatMap(() => doRequest("http://test3.com"))
    .do(response => {
      observer.next(new InfoMessage("request3"));
      observer.complete();
    }).subscribe();
})

I prefer to delay subscription and delegate it to the caller of doAllRequests(). Any suggestions?

Update: proposed solution by Quentin

This method functions well and is more efficient for executing large scripts with multiple requests, concerning code verbosity.

As this is now the method I am using, I am changing my accepted answer. However, Martin, I appreciate your input! Are we good?

Answer ā„–1

Instead of making separate requests, why not combine all your requests into a single stream by using the already-observable doRequest() method? You can achieve this with the forkJoin operator:

combineAllRequests() : Observable<InfoMessage> {
 return forkJoin(
  doRequest("http://test1.com"),
  doRequest("http://test2.com"),
  doRequest("http://test3.com")
 ).pipe(
  mergeMap((responsesArray: any[]) => from(responsesArray)),
  map((response: any) => new InfoMessage(response))
 );
}
this.combineAllRequests().subscribe();

Answer ā„–2

If you want to make each HTTP call independent of the previous one, you can easily chain them using concatMap:

Observable.create((observer: Observer<InfoMessage>) => {
  doRequest("http://test1.com")
    .do(response => observer.next(new InfoMessage("request1 done")))
    .concatMap(() => doRequest("http://test2.com"))
    .do(response => observer.next(new InfoMessage("request2")))
    .concatMap(() => doRequest("http://test3.com"))
    .do(response => {
      observer.next(new InfoMessage("request3"));
      observer.complete();
    });
})

Just remember to ensure that you return Observable.create from your function and then subscribe to it.

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

Enhancing the Mario gaming experience with a bespoke Typescript camera feature

I am working on creating an educational Mario game without the use of PhaserJS or any other engine. Currently, I am faced with the challenge of implementing a camera that can follow Mario as he moves. As it stands, Mario can walk off the screen in one di ...

Encountered an error: "switch/mergeAll/flatten is not a valid function" when working with the http driver

As I delve into learning CycleJS, one thing that has caught my attention is the usage of Cycle's HTTP Driver. It seems that in order to reach the stream level, merging the response stream stream with RxJS switch/mergeAll is essential. However, when at ...

The process of transferring information from a JSON API to TypeScript models

When working with my JSON API in my services, I need to pass the data to my models. What is the most efficient way to accomplish this task? Currently, I am following this process: import { Attachment } from '.'; export class Contact { id: nu ...

A TypeScript class method that returns a different function

I have created a class with the following implementation: import {Request, Response, Router} from 'express'; import {IAccessTokenMiddleWare} from "./IAccessTokenMiddleWare"; class AccessTokenMiddleWare implements IAccessTokenMiddleWare { ...

Get rid of the strange border on the material dialog

I am struggling with the Angular material 6 dialog component as it is displaying a strange border. I have attempted to remove it using the code below, without success. Interestingly, when I apply the style inline in the browser, it works fine. Any suggesti ...

Converting Typescript Object Types to Array Types with Tuple Structures

Presently, I have the following: interface Obj { foo: string, bar: number, baz: boolean } The desired outcome is to convert this interface into the tuple format below: [string, number, boolean] Is there a way to achieve this conversion? Up ...

Do the two types of updater functions for setState in React hold the same value?

Recently, I came across the concept of using updater functions for setState in React. After learning about this, I noticed it being implemented in two different ways. Imagine having a state object structured like this: interface State { readonly expand ...

Can you explain how TypeScript module resolution handles global values?

After installing @types/jest, I noticed that jest's corresponding typescript definitions were detected automatically. However, when I started implementing integration tests with cypress (which uses mocha), I encountered a problem where mocha type defi ...

`AngularJS Voice Recognition Solutions`

In my quest to implement voice recognition in an AngularJS application I'm developing for Android and Electron, I've encountered some challenges. While I've already discovered a suitable solution for Android using ng-speech-recognition, fin ...

Exploring routing within a Higher Order Component in React Native

I am looking to implement a file existence check on every page of my app. The idea is that if a specific file exists, the user should be redirected to another page. One solution I have considered is using a Higher Order Component (HOC) for this purpose. A ...

File manager built with React, allowing users to easily remove files stored in the browser or on a local host

I am in the process of developing a reactjs based web application for file management on my local machine. Currently, I am utilizing code from a project located at https://github.com/knyzorg/simple-file-explorer which employs WebSockets to display files. M ...

Encoding an object in TypeScript with functions and a looping reference network

Currently, I'm dealing with a complex project in TypeScript that heavily relies on object-oriented programming, resulting in a quite intricate object graph (including objects that indirectly point to themselves). My need now is to serialize this graph ...

Countdown component in Ant Design failing to display correct date

Iā€™m currently working on developing a specific date component using react in conjunction with antd. Below is the code snippet I am utilizing: import { Statistic, Col, Row } from 'antd'; const { Countdown } = Statistic; const deadline = Date.pa ...

Using Typescript to inherit from several classes with constructors

I am trying to have my class extend multiple classes, but I haven't been able to find a clean solution. The examples I came across using TypeScript mixins did not include constructors. Here is what I am looking for: class Realm { private _realms: C ...

In TypeScript, callback return type inference is not performed for objects

When working with TypeScript, I've noticed that it usually infers the type correctly without me having to explicitly define it. For example: function myFunction<T>(callback: () => T) { return callback(); } const result = myFunction(() = ...

Error messages are displayed for attribute directives even in a freshly generated Angular project

I am experiencing an issue with a newly created Angular Project in Visual Studio Code where attribute directives like [ngClass], [ngSwitch], and others are showing errors in the .html file. Here is the standard app.component.html file created as part of "n ...

Mastering the art of connecting content within Prismic

I have been working on creating a mega menu for my website header, but I am encountering a type error. Has anyone else faced this issue before and how did you resolve it? I am currently importing the generated types from @/prismicio-types. Here is an exam ...

Angular ViewChild using a Directive as a selector results in a value of null

I have been working on a test component that includes an example of two directives, with one being used as an attribute directive. I am utilizing the ViewChild decorator to access these directives in the ngAfterViewInit handler. However, when I try to retr ...

What is preventing typescript from inferring these linked types automatically?

Consider the following code snippet: const foo = (flag: boolean) => { if (flag) { return { success: true, data: { name: "John", age: 40 } } } return { success: false, data: null } ...

Unable to retrieve data from localStorage in Next.js

Unable to access localStorage in Nextjs. Code works as expected without errors, but the terminal throws: ReferenceError: localStorage is not defined at MainGrid (./app/components/WeightDisplay/MainGrid.tsx:17:96) 8 | // Initialize states for prefe ...