Stackflow
Stackflow

Reputation: 1

Angular- Consume a restendpoint and then call another endpoint in the result

I am new in angular and trying to learn it.

I am trying to consume a endpoint : http://localhost:9061/services

which will return below result :

[
"http://localhost:9001/info",
"http://localhost:9002/info",
"http://localhost9003/info",
"http://localhost:9011/info",
"http://localhost:9004/info",
"http://localhost:9005/info",
"http://localhost:9006/info"
]

then i need to call each endpoint of the result.

For ex -: http://localhost:9005/info

which will return below result:

{
applicationName: "catlaog-service",
buildVersion: "1.0,0",
buildTimestamp: "2020-07-30T08:01:06.776Z"
}

Similarly , i need to call other endpoint in result and show the result in the list.

Can someone help me to how to do it angular.

This is what i tried :

    this.getRegisteredServices().subscribe( result => {
       this.getInfo(result)
         .subscribe((response) => {
           this.applicationName = response.applicationName;
           this.version = response.buildVersion;
           this.buildTimestamp = response.buildTimestamp;
         })
    });


 public getInfo(result): Observable<ServiceInfo> {
    return <Observable<ServiceInfo>> this.restClient.getJSON(result);
  }

  public getRegisteredServices(): Observable<any> {
    return <Observable<any>> this.restClient.getJSON(this.serviceUrl + "/services");
}

export class ServiceInfo{

  applicationName: string;
  buildVersion: string;
  buildTimestamp: string;

  constructor(applicationName: string, buildVersion: string, buildTimestamp: string) {
    this.applicationName = applicationName;
    this.buildVersion = buildVersion;
    this.buildTimestamp = buildTimestamp;
  }

  public toString() {
    return "<ServiceInfo>:[applicationName='" + this.applicationName + "'"
      + ",version:'" + this.buildVersion + "'"
      + ",buildTimestamp:'" + this.buildTimestamp + "'"
      + "]";
  }
}

Upvotes: 0

Views: 328

Answers (1)

Barremian
Barremian

Reputation: 31125

Assuming this.getInfo() function triggers a single HTTP request for an URL, you could use RxJS switchMap higher-order mapping operator to switch the response from http://localhost:9061/services to another observable. For the inner observable, you could use RxJS forkJoin function to combine multiple observables (in this case, multiple HTTP requests).

Try the following

this.getRegisteredServices().pipe(
  switchMap(apps => forkJoin(apps.map(app => this.getInfo(app))))
).subscribe(
  res => this.appList = res,
  err => { }
);

Array map function is used to convert the response array from first request ['url1', 'url2', ...] to [this.getInfo('url1'), this.getInfo('url1'), ...]

The output will be of the form

this.appList = [
  {
    applicationName: "auth-service",
    buildVersion: "1.0,0",
    buildTimestamp: "2020-07-30T08:01:06.776Z"
  },
  {
    applicationName: "config-service",
    buildVersion: "1.0,0",
    buildTimestamp: "2020-07-30T08:01:06.776Z"
  },
  ...
]

Update: use ServiceInfo class from OP

You could map each request to return an object of the class ServiceInfo. Try the following

appList: ServiceInfo[] = [];

this.getRegisteredServices().pipe(
  switchMap(apps => 
    forkJoin(apps.map(app => 
      this.getInfo(app).pipe(map(res => 
        new ServiceInfo(res['applicationName'], res['buildVersion'], res['buildTimestamp'])
      ))
    ))
  )
).subscribe(
  (res: ServiceInfo[]) => this.appList = res,
  err => { }
);

Upvotes: 1

Related Questions