Warm tip: This article is reproduced from serverfault.com, please click

Merge two observables into new one

发布于 2020-11-30 17:12:08

I have to merge the result of 2 different kind of http request:

  • Request 1 : get proyects. Returns an Observable<ProjectDTO[]>
  • Request 2: depending on the numbers of projects, I have to do N calls (one per project in the list in the first call). Returns an object ItemsProject

With this I receive the counters of items per project. The DTO's

ProjectDTO {
  name: string;
  id: number;
}

ItemsProject {
 idProject: number;
 itemsCount: number;
}

In the view, I have to display only two things: project name and items per project.

What I do is the following:

    this.vlService.getProjects().pipe(
        mergeMap(projects => {
          this.projects = projects;
          return forkJoin(
            projects.map(project => {
              const projectCount: ItemsProject = {
                idProject: project.idProjects,
                count: 0,
              };
              return this.vlService.getTotalItemsPerProject(projectCount);
            })
          );
        })
      )
      .subscribe(result => {
        console.log('VCOMP | result --> ', result)
      });

It works, but in the result I have an array of ItemsProjects. Then, I should replace the ItemProject.idProject by Project.name.

As a result, i want an array of items like this:

ProjectCounter {
 name: string;
 items: number;
}

Is there a better way to achieve this? Thanks in advance

Questioner
Aw3same
Viewed
0
chrnx 2020-12-01 01:44:07

You could try passing the project itself on in the stream, so you can still access the name at the end and don't break your interface structure.

I haven't tested it but something like this should work:

this.vlService.getProjects().pipe(
  mergeMap(projects => from(projects).pipe(
    concatMap(project => forkJoin({
      project: of(project),
      items: this.vlService.getTotalItemsPerProject(projectCount).pipe(first())
    })),
    toArray()
  ))
).subscribe(result => {
  console.log('VCOMP | result --> ', result)
});

This should result in an array of objects with project: ProjectDTO and items: ItemsProject[]