How about: "Loop through an array of objects fetched from an observable and initiate an HTTP request for each object's ID?"

Using Angular routing, in the component's ngOnInit method, I retrieve a genre ID through an observable. Within this observable, a service method is called that makes an HTTP request.

  this.movies: Movie[];

  ngOnInit() {
    this.route.paramMap.subscribe(param => {
      let id = +param.get('id');

      this.movieService.getMoviesByGenres(id).subscribe( response => {
        this.movies = response['results'];
      });
    });
  }

The resulting data looks like this:

   "results": [
    {
      "vote_count": 664,
      "id": 287947,
      "video": false,
      "vote_average": 7.4,
      "title": "Shazam!",
      .
      .
      .
    },
    {
      "vote_count": 3623,
      "id": 299537,
      "video": false,
      "vote_average": 7.2,
      "title": "Captain Marvel",
      .
      .
      .
    }, ...
   ]

However, the movies returned do not include cast information. To fetch the casts for each movie, an additional HTTP request needs to be made for each movie and the cast details need to be added to the movies[i].cast array.

Therefore, the desired functionality can be achieved as follows:

  ngOnInit() {
    this.route.paramMap.subscribe(param => {
      let id = +param.get('id');

      this.movieService.getMoviesByGenres(id).subscribe( response => {
        this.movies = response['results'];

        //pseudo code
        foreach(this.movies as movie) {
             this.movies[current element].casts = 
                  this.movieService.getCastByMovieId(movie.id);
        }
      });
    }); 
  }

This means getting movies by genre, then iterating through the movies[] array upon receiving the results. For each movie, call a method to get the cast based on the movie ID and add the casts to the movie's casts: string [] property. Finally, return this.movies: Movies[] which now includes the cast information as well.

Answer №1

While utilizing Angular, you can optimize your code with RxJS by implementing the following approach:

public ngOnInit(): void {
  this.route.paramMap.subscribe(param => {
    let id = +param.get('id');

    this.movieService.getMoviesByGenres(id).pipe(
      map(response => response['results']),
      mergeMap((movies: any[]) => {
        return forkJoin(
          movies.map(movie => {
            return this.movieService.getCastByMovieId(movie.id)
              .pipe(
                map((res: any) => {
                  movie.cast = res;
                  return movie;
                })
              );
          })
        )
      }))
      .subscribe(movies => {
        // Your logic here
      });
  })
}

In essence, you retrieve movies first and then group their cast details using forkJoin to execute requests in parallel while preserving order. By adding the cast information to each movie object and returning the complete array, you can track the completion of execution effectively.

Remember that a failure within forkJoin will halt the entire process, so ensure to handle errors individually for each request.

Answer №2

If you're looking to implement a similar functionality, consider the following approach:

ngOnInit() {
    const self = this; 
    this.route.paramMap.subscribe(param => {
      let id = +param.get('id');

      self.movieService.getMoviesByGenres(id).subscribe( response => {
        self.movies = response['results'];
        for(let movie of self.movies){
            self.movieService.getCastByMovieId(movie.id).subscribe((result) => {
                self.movies[current element].casts = result;
           });
        }
      });
    }); 
  }

The use of 'self' as a variable is essential here since the context within the inner service differs from that of the component. In essence, 'this' has different meanings for the service and the component.

Note: Ensure that your movieService returns the HTTP request properly, or else it will not return Observable, making it impossible for the component to subscribe to it.

Answer №3

To iterate through the array, we can send endpoint requests one by one.

Within TypeScript file:

  let dataToUpdate = [{...}, {...},...];

this.dataService.sendData(dataToUpdate).subscribe(
    response => console.log(response),
    error => console.error(error),
    () => console.info("All requests processed") 
);

Inside Service file:

import { from } from "rxjs";
import { concatMap } from "rxjs/operators";

   ...

sendData(dataToUpdate){

  return  from(dataToUpdate).pipe(
  concatMap(payload => this.http.post('http://localhost:4200/api/data-handler', payload))
  );
}

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

Ways to organize JSON information in Angular by date basis?

I am working on a project where I need to organize multiple JSON objects into an array based on their date data, with the date field serving as the key. ...

The combination of a reactive form and the latest object may result in a potential null or undefined

Is it possible to update a FormArray based on the values of two other controls? After thorough checks, TypeScript is indicating issues with 'st' and 'sp'. The object is potentially null. Can someone identify the errors in this code ...

Tips for choosing a subset of objects within a larger array of objects and generating a new array from them?

I am working with an array of 3586 objects, each containing various products. How can I create and store a new array that only includes the products from a specific index? console.log listarPorReferencia() { this.linxService.listarPorReferencia().subs ...

Rendering Information in Angular 4 Through Rest API

Encountering issues displaying data from my local express.js REST API, organized as follows: people: [{ surname: 'testsurname', name: 'testname', email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemai ...

Enhance Vue TypeScript components with custom component-level properties

In my vue2 project, I am utilizing vue-class-component along with vue-property-decorator. My goal is to implement component-level security validation for each component when it loads. I imagine implementing it with a signature like this: @Component @Secur ...

Tips for incorporating JavaScript modules into non-module files

Learning how to use js modules as a beginner has been quite the challenge for me. I'm currently developing a basic web application that utilizes typescript and angular 2, both of which heavily rely on modules. The majority of my app's ts files ...

Ecommerce Template for Next.js

I am new to the world of web development and I have a project involving customizing a Next.js ecommerce template. Since I'm still learning programming, I would appreciate a simple summary of the steps I need to take in order to achieve this. The speci ...

Using optional chaining on the left side in JavaScript is a convenient feature

Can the optional chaining operator be used on the left side of an assignment (=) in JavaScript? const building = {} building?.floor?.apartment?.number = 3; // Is this functionality supported? ...

Using the parameter of type 'never' is necessary as per the TypeScript error message, which states that the argument of type 'string' cannot be assigned to it. This error persists even when

const index = selectedActivities.value.indexOf(activity_id); I encountered a TypeScript error saying 'Argument of type 'string' is not assignable to parameter of type 'never'. How can I fix this issue? ...

What scenarios call for utilizing "dangerouslySetInnerHTML" in my React code?

I am struggling to grasp the concept of when and why to use the term "dangerous," especially since many programmers incorporate it into their codes. I require clarification on the appropriate usage and still have difficulty understanding, as my exposure ha ...

Even after calling ChangeDetectorRef.detectChanges, the ngOnChanges hook failed to trigger

export class AppComponent implements OnInit, OnChanges { @Input() value: number; constructor( private cdr: ChangeDetectorRef ) {} ngOnInit() { of(1).subscribe(v => { this.value = v; console.log(1); this.cdr. ...

Is it possible to maintain the Spring default login page while turning off CSRF protection?

I have been working on a Spring+Angular site and the default login page was functioning well for me initially. The issue arose when I needed to turn off CRLF validation to be able to make POST requests from my Angular application, so I disabled it. Unfor ...

Guide to implementing validation in an angular 2 dropdown using the Model-driven Approach

When the user clicks the submit button, the dropdown validation does not occur. I want the form to be validated if the user does not select any value, and in that case, the form state should be invalid. In my scenario, I have disabled the submit button whe ...

Determine whether there is greater available space above or below a specific element within the DOM

I'm looking to create a dynamic layout where an input field is accompanied by a list in a div, positioned either above or below depending on available space. This setup needs to account for the fact that the input field could be located anywhere on th ...

Mapping a TypeScript tuple into a new tuple by leveraging Array.map

I attempted to transform a TypeScript tuple into another tuple using Array.map in the following manner: const tuple1: [number, number, number] = [1, 2, 3]; const tuple2: [number, number, number] = tuple1.map(x => x * 2); console.log(tuple2); TypeScript ...

An issue occurred: TypeError - Unable to access the 'subscribe' property of an undefined object during a POST HTTP request in Angular [8]

I'm currently attempting to send data to a REST API using Postman. I am encountering an issue where I receive the error "Cannot read property 'subscribe' of undefined" when making a POST HTTP call, as shown in the console log: https://i.sta ...

Modify an array by incorporating values from another array that have a matching property

I have two arrays that look like this let array1 = [{ 'id': 1, 'name': 'A' }, { 'id': 2, 'name': 'B' }, { 'id': 3, 'name': ' ...

Exploring the Angular RouterModule within a Java WAR Deployment

In my Angular 6.0.5 application, I leverage Angular's Routing feature to define paths like: http://localhost:8080/area http://localhost:8080/barn http://localhost:8080/tower During development, running the app with ng serve allows me to directly en ...

Creating cascading select fields in Angular using form controls

Encountering a peculiar issue with Angular Reactive Forms and a dependent drop-down list, undoubtedly stemming from my lack of expertise. I aim to establish the options in the second drop-down reliant on the selection in the first drop-down. Upon changing ...

The Angular directive HostBinding is often used in conjunction with the

Is it possible to add a routerLink to the Host Element within an Angular Component? I attempted the following: @HostBinding('routerLink') routerLink = '/my-route' However, clicking on the component does not navigate to the specified ro ...