it-swarm.com.de

Angular - HttpClient: Map Ruft das Ergebnis des Methodenobjekts der Array-Eigenschaft ab

Ich rufe eine API auf, die ein JSON-Objekt zurückgibt. Ich brauche nur den Wert des Arrays, um ein Observable abzubilden. Wenn ich ein API anrufe, das nur das Array zurückgibt, funktioniert mein Serviceabruf.

Unten ist mein Beispielcode .. 

// my service call ..
import { Injectable } from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {Show} from '../models/show';
import {HttpClient} from '@angular/common/http';

@Injectable()
export class MyService {

  constructor(private http: HttpClient ) { }


  findAllShows(): Observable<Show[]> {
    return this.http
      .get<Show[]>(`${someURL}/shows`)
  }
}

Wenn die Rückgabe ein JSON-Objekt wie das folgende ist, schlägt dies fehl. 

// Service API that FAILS ...
{
  "shows": [
    {
      "id": "123f9165-80a2-41d8-997a-aecc0bfb2e22",
      "modified": "2017-08-13 15:54:47",
      "name": "Main Show1"
    },
    {
      "id": "456f9165-80a2-41d8-997a-aecc0bfb2e22",
      "modified": "2017-08-14 15:54:47",
      "name": "Main Show2"
    },
    {
      "id": "789f9165-80a2-41d8-997a-aecc0bfb2e22",
      "modified": "2017-08-17 15:54:47",
      "name": "Main Show3"
    }
  ]
}

Jetzt funktioniert das, wenn ich nur das Array zurückschicke 

// Service API that Works ...
[
    {
      "id": "123f9165-80a2-41d8-997a-aecc0bfb2e22",
      "modified": "2017-08-13 15:54:47",
      "name": "Main Show1"
    },
    {
      "id": "456f9165-80a2-41d8-997a-aecc0bfb2e22",
      "modified": "2017-08-14 15:54:47",
      "name": "Main Show2"
    },
    {
     "id": "789f9165-80a2-41d8-997a-aecc0bfb2e22",
      "modified": "2017-08-17 15:54:47",
      "name": "Main Show3"
    }
  ]

Wie ordne ich das JSON-Objekt Observable einem Array Observable zu?

9
Netwobble

Sie können einfach .map() Ihren http-Aufruf (Observable) aufrufen, um den gewünschten Datentyp zurückzugeben.

findAllShows(): Observable<Show[]> {
    return this.http
        .get(`${someURL}/shows`)
        .map(result=>result.shows)
}

Ihre httpClient.get() sollte eine Observable zurückgeben, die Sie ausdrücklich als Observable<Show[]> angegeben haben. Sie .map() ist ein Operator, der das Beobachtbare in einen neuen verwandelt.

Weitere Informationen zum .map()-Operator: http://reactivex.io/documentation/operators/map.html

11
CozyAzure

.map(res=> res['shows'] ) macht den Trick

3
Sreejith sreeji

Die letzte HttpClient, die anstelle von http verwendet werden sollte, hat keine map-Methode. Sie sollten es zuerst mit import { map } from 'rxjs/operators';.__ importieren und dann folgendermaßen verwenden:

this.http.get(`${someURL}/shows`).pipe(
        map(res => res['shows'])
    )
2
MajidJafari

Thanks All, Ich konnte eine Lösung finden, indem ich die Antworten von @ Arun Redhu kombinierte, indem ich eine Übertragungsobjektschnittstelle bereitstelle, die der Server zurücksendet. Dann Lösung, die von @CozyAzure bereitgestellt wird. Verwenden Sie die .map (), um ein Observable in die richtige Observable Show [] umzuwandeln. 

Vollständige Lösung für Interessenten.

import {Observable} from 'rxjs/Observable';
import {Contact} from '../models/show';
import {environment} from '../../../environments/environment';
// Use the new improved HttpClient over the Http
// import {Http, Response} from '@angular/http'; 
import {HttpClient} from '@angular/common/http';

// Create a new transfer object to get data from server
interface ServerData {
  shows: Show[];
}

@Injectable()
export class ShowsService {

  constructor(private http: HttpClient ) { }

// want Observable of Show[]
  findAllShows(): Observable<Show[]> {  
    // Request as transfer object <ServerData>
    return this.http
      .get<ServerData>(`${apiURL}/shows`)
     // Map to the proper Observable I need 
      .map(res => <Show[]>res.shows); 

  }
}

Alles super jetzt !!! Vielen Dank . Abhängig von den zurückgegebenen Daten kann ich sie entweder direkt verwenden oder das richtige Observable zuordnen, das ich brauche. 

1
Netwobble

Dafür gibt es zwei Ansätze. Sie können den Operator .map vom Beobachtbaren verwenden, um einen Beobachtertyp in einen anderen zu mappen, und der zweite Ansatz wird nur mit Hilfe der Schnittstelle verwendet. 

1. Ansätze (mit Hilfe von .map)

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';

import 'rxjs/add/operator/map';

interface ItemsResponseObj {
    id: string,
    modified: string,
    name: string
}

interface ItemsResponse {
    shows: Array<ItemsResponseObj>;
}

@Injectable()
export class AppService {

    constructor(private http: HttpClient) { }

    getData(): Observable<ItemsResponseObj[]> {
        return this.http.get<ItemsResponse>('api/api-data.json')
            .map(res => res.shows);
    }

}

und im zweiten Ansatz mit Hilfe von Wrapping-Schnittstellen

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { Observable } from 'rxjs/Observable';

interface ItemsResponseObj {
    id: string,
    modified: string,
    name: string
}

interface ItemsResponse {
    shows: Array<ItemsResponseObj>;
}

@Injectable()
export class AppService {

    constructor(private http: HttpClient) { }

    getData(): Observable<ItemsResponse> {
        return this.http.get<ItemsResponse>('api/api-data.json')
    }

}
0
Arun Redhu