Performing a series of Http Get requests in Angular 2 with an array that can

Seeking assistance with an Observable http sequence that involves making two dependent http calls to an api. The first call returns an Array of Urls, and the second call makes get requests for each url in the array and then returns the responses on the stream. If I hard code one of the dependent requests, I can successfully retrieve one of the titles I need:

search(character): Observable<any> {
let that = this
let queryUrl: string = character.url;
return this.http.get(queryUrl)
  .map((response: Response) => {
    this.characterResults = response.json().films
    return this.characterResults
        //Example response: 
        // ["https://api.com/films/1", "https://api.com/films/2", "https://api.com/films/3", "https://api.com/films/4"]
  })
  .flatMap((film) => {
    return that.http.get(film[0])
    .map((response: Response) => {
      return response.json().title
    })
  })
}

getApiData(character) {
    this.apiService.search(character)
    .subscribe((results) => { // on sucesss
          console.log(results)
        },
        (err: any) => { // on error
          console.log(err);
        },
        () => { // on completion
          console.log('complete')
        }
      );

However, trying to iterate over the array using forEach and make all the http calls simultaneously results in this error:

browser_adapter.js:84 EXCEPTION: TypeError: Cannot read property 'Symbol(Symbol.iterator)' of undefined

Ideally, I am looking for a refined approach to make those subsequent calls in parallel with the result array from the first call. Unfortunately, I am having difficulties identifying which RxJS method could assist me. Any guidance or suggestions would be greatly appreciated.

Answer №1

There are two different approaches you can take for streaming individual results. One option is to use flatMap, which is versatile and can flatten various data structures like Arrays, Promises, or Observables. In this case, you can chain requests together as shown below:

search(character): Observable<any> {
  return this.http.get(character.url)
    .flatMap((response: Response) => response.json().films)
    .flatMap((film: string) => this.http.get(film), 
             (_, resp) => resp.json().title)
}

getApiData(character) {
    this.apiService.search(character)
      .subscribe((results) => { // on success
          //Print each individual result from the URLs
          console.log(results)
        },
        (err: any) => { // on error
          console.log(err);
        },
        () => { // on completion
          console.log('complete')
        }
      );

Alternatively, you can utilize forkJoin to gather an array of results:

return this.http.get(character.url)
  .flatMap((response: response) => 
             //Wait until all requests complete before emitting
             //an array of results
             Observable.forkJoin(response.json().files.map(film => 
               this.http.get(film).map(resp => resp.json().title)
             ));

Edit 1

To explain the second argument of flatMap more thoroughly, it accepts a function that receives the original value passed to the first selector method along with a result from the flattening operation. So, if the first selector returns a and an Observable of [1, 2, 3], the second selector will be called three times with arguments (a, 1), (a, 2), and (a, 3).

If you need multiple values, consider using an additional mapping operator for clarity in your code flow.

.flatMap((film: string) => this.http.get(film),
         (film: string, resp: Response) => resp.json())
//Use Typescript's destructuring syntax to extract desired values
//and create a new object with those fields
.map(({date, title}) => ({date, title}));

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

Learning to extract information from elements within components in a flexbox using Angular

Is there a way to access the element width of child components within a parent component that utilizes flex box? I am hoping to determine if the list is overflowed so I can adjust the visibility of elements accordingly. If an overflow occurs, I would like ...

What is the best way to include a button at the bottom of a Material UI table?

I've been working with Material UI in React TypeScript and I'm having trouble adding a button at the bottom that leads to a form. Despite my attempts, I haven't been successful. Can someone please help me with this? I just need a simple butt ...

Tips for fixing TypeScript compiler error TS2339: Issue with accessing 'errorValue' property in Angular 5 project

Within a component, I have developed a function to manage errors returned from a Rest Service and determine the corresponding error message to display to the user. This method accepts an error object (custom data structure from the service), navigates to e ...

Struggling with getting Angular 2 npm start to function properly, as it keeps returning Exit status

I am facing an issue with my angular 2 application on my laptop. It works fine for me, but when my teammate tries to clone it using git, he encounters a strange error when running npm start. He has node.js installed and the files are exactly the same. He ...

I am currently working on an Angular 8 project and experiencing difficulties with displaying a specific value from a JSON object in my template using an ngFor loop

Apologies if I am not familiar with all the terms, as I am mostly self-taught. I started with Udemy and then turned to Stack Overflow to tackle the more challenging aspects. This platform has been incredibly valuable and I am truly grateful for it. Now, l ...

A guide on implementing a "Select All" trigger in mat-select with Angular8/Material

Here is the code I have created: <mat-form-field appearance="outline"> <mat-label>Handler Type</mat-label> <mat-select multiple [(value)]="handlerType"> <mat-option *ngFor="let handler of handlerT ...

Angular integration problem with aws-amplify when signing up with Google account

I am attempting to integrate AWS-Amplify(^4.3.0) with angular-12 and typescript (4.3.5). I have followed the documentation to configure amplify properly, but when trying to start the app, I encountered some amplify errors as shown below. Warning: D:\G ...

Error message encountered in Nativescript app on Android only appears in Release build due to java.lang.Unsatisfied

I am encountering an issue with my NativeScript app where it runs smoothly in debug mode but crashes on startup in release mode. The logs reveal the following error message: 01-15 16:23:01.474 12229 12229 E script.demo: No implementation found for void co ...

Encountering a 404 error when trying to access the rxjs node_module

While attempting to compile an angular2 application, I encountered the following issue: Error: XHR error (404 Not Found) loading http://localhost:3000/node_modules/rxjs(…) systemjs.config.js (function(global) { // map tells the System loader whe ...

Tips for setting NgForm value within an Observable and verifying its successful implementation

Exploring the functionality of NgForm, I am testing to validate if the value of a form gets updated when the state of the store changes. @ViewChild('form') form: NgForm; ngOnInit() { this.subscription = this.store.select('shoppingList&apos ...

The PhpStorm code completion feature is not functioning properly when working with TypeScript code that is distributed through NPM

I am facing an issue with two NPM modules, which we will refer to as A and B. Both modules are written in TypeScript and compile into CommonJS Node-like modules. Module B has a dependency on module A, so I have installed it using the command npm install ...

ESLint refuses to be turned off for a particular file

I am in the process of creating a Notes.ts file specifically for TypeScript notes. I require syntax highlighting but do not want to use eslint. How can I prevent eslint from running on my notes file? Directory Structure root/.eslintignore root/NestJS.ts r ...

Discover the method of extracting information from an object and utilizing it to populate a linechart component

Object Name: Upon calling this.state.lineChartData, an object is returned (refer to the image attached). The structure of the data object is as follows: data: (5) [{…}, {…}, {…}, {…}, {…}, datasets: Array(0), labels: Array(0)] In the image p ...

What is the best way to duplicate a Typescript class object while making changes to specific properties?

I have a Typescript cat class: class Kitty { constructor( public name: string, public age: number, public color: string ) {} } const mittens = new Kitty('Mittens', 5, 'gray') Now I want to create a clone of the inst ...

Unable to execute OAuth2 with Okta using angular-oauth2-oidc framework

Looking to create an authentication module for an Angular application using Okta as the identity provider and implementing the angular-oauth2-oidc flow. Following a guide here: . However, encountering errors when running the web app. How can I troubleshoot ...

When attempting to compile Angular in production mode, errors may arise such as the Uncaught SyntaxError caused by an Unexpected token '<'

I encountered some errors in the console of my Angular 8 app. When I opened the browser window, it was blank and this error appeared: Uncaught SyntaxError: Unexpected token '<' https://i.sstatic.net/a16DD.png I tried running different ng bui ...

What is the process of creating an asynchronous function that will resolve a promise when the readline on('close') event is triggered within it in Typescript?

Here's a code snippet I'm working with: private readFile() { var innerPackageMap = new Map<string, DescriptorModel>(); // Start reading file. let rl = readline.createInterface({ input: fs.createReadStream(MY_INPUT_FILE ...

Imitate a required component in a service

I am currently facing an issue with mocking a dependency in a service. I am not sure what is causing the problem. It's not the most ideal class to test, but I am mainly focused on code coverage. Below is the code for the service: @Injectable() export ...

Utilizing Angular 2 with Bootstrap's popup modal feature

Is it possible to implement a popup modal in my Angular 2 application without relying on popular packages like ng2-opd-pop or similar solutions? I have included Bootstrap by importing it in my styles.css using '@import '../../../Content/bootstra ...

Can classes be encapsulated within a NgModule in Angular 2/4?

Looking to organize my classes by creating a module where I can easily import them like a separate package. Take a look at this example: human.ts (my class file) export class Human { private numOfLegs: Number; constructor() { this.numOfLegs = 2 ...