简体   繁体   中英

Merge array with http get result rxjs angular

So, this is probably something very simple, but i just don't see the light.

I have a http get request with RXJS in Angular , it looks something like this in my service:

getData():Observable<any>{
    let url = 'http://www.randomUrl/data';

    return this.http.get(url)
        .map((res:Response)=> {let body = res.json(); return body;})
        .concatMap((data)=>this.getComputers(data))
        .concatMap((data)=>this.getComputer(data))
        .catch(this.handleError);
}

// The information I receive in getComputers is the next one, from which i only create a new JSON Array with numberID, computers.hostname, computers.id, and computers.installation.property1

// NOTE: There can be multiple computers under one numberId

[
  {
    "numberId": "948004830011",
    "computers": [
      {
        "hostname": "COMPUTER-A1",
        "id": "COMPUTER-A1",
        "installation": {
          "property1": "NONE",
          "property2": "NONE",
          "property3": "NONE"
        }
      },
...
    ]
  },
  {
    "numberId": "848004830011",
    "computers": [
      {
        "hostname": "COMPUTER-A4",
        "id": "COMPUTER-A4",
        "installation": {
          "property1": "NONE",
          "property2": "NONE",
          "property3": "NONE"
        }
      }
....
    ]
  }
]

//get All Computers

  getComputers(data): Observable<any[]> {
    let jsonArr = [];
    for (let i = 0; i < data.length; i++) {
      for (let j = 0; j < data[i].computers.length; j++) {
        jsonArr.push({
          number: data[i].number,
          id: data[i].computers[j].id,
          property1: data[i].computers[j].installation.property1
        });
      }
    }

    return Observable.of(jsonArr);
  }

//In getComputer I receive the next data:

  [
  {
    "number": "948004830011",
    "id": "COMPUTER-A1",
    "property1": "NONE"
  },

....

]

//Now, in getComputer I get more information based on the property1 of each computer, that's why i created an array observables where i could collect the http requests results and do a forkJoin at the end. This works, however, I want to include the number, id and property1 value in each one of them.

  getComputer(data):Observable<any[]>{
    for (let i = 0; i < data.length; i++) {

//if I add the Observable of a value in the observables array, it won't separate the results from each computer, it will bring all the results separated.
    // observables.push(Observable.of(data[i].id));

        let url = 'url' + '/' + data[i].id;
       observables.push(this.http.get(url)
         .map((res: Response) => { let body = res.json().children; return body; })     
         .catch((res: Response) => Observable.of(null))
         .catch(this.handleError));
    }
    return Observable.forkJoin(observables);
  }

// I'm currenty receiving the next data:

[
// I want to add here number, hostname, and id from each computer
  [
    // computer information
  ],
  ...
  [..
    // computer information
  ],
  ...
]

// If i use observables.push(Observable.of(data[i].id)), I receive an array where computer id is 0 , number id is 1, computer data is 2, and then the next computer id is 3.

[
  "COMPUTER-A1",
  "948004830011",
  [
    // computer information
  ]
  ,
  "COMPUTER-A2",
  "948004830011",
  [
    // computer information
  ],
  "COMPUTER-A3",
  "948004830011",
  [
     // computer information
  ],
    ...
]

I want however, the information related to each computer in one array, that is, computer id will always be 0 in each array, computer number 1, and computer information 2. How could I achieve this? I don't know the exact number of computers there exist. Is it possible to create something like the next one??

[
[
  "COMPUTER-A1",
  "948004830011",
  [
    // computer information
  ]
],
[
  "COMPUTER-A2",
  "948004830011",
  [
    // computer information
  ]
],

...
]

I would take a different approach to this, you need to know that rxjs and requests in general are asynchronous so don't try to make them synchronous if you don't have to.

For the example lets assume the response of your http request is

[
{id: "COMPUTER-A1", number: "948004830011"},
{id: "COMPUTER-A2", number: "948004830011"}
]

Now if you handle this data like:

return this.http.get(url)
        .map((res:Response)=> res.json())
        .map((data)=>data.map((d) => this.getComputersData(d)))
        .catch(this.handleError);

public getComputersData(data: any): any {
  let computersData: any = data;
  this.getComputers(computersData.number)
      .subscribe((computers) => computersData.computers = computers);
  return computersData;
}

private getComputers(computerNumber: string): Observable<any> {
  this.http.get('some/url/to/get/computers/' + computerNumber);
}

The final structure would look like:

[
  {
    id: 'COMPUTER-A1',
    number: '948004830011',
    computers: [
      // whatever data you return from getComputers()
    ]
  },
  {
    id: 'COMPUTER-A2',
    number: '948004830011',
    computers: [
      // whatever data you return from getComputers()
    ]
  }
]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM