web-dev-qa-db-de.com

So ordnen Sie eine Antwort von http.get einer neuen Instanz eines eingegebenen Objekts in Angular 2 zu

Ich versuche zu verstehen, wie das Ergebnis eines Serviceaufrufs mit http.get und Observables in Angular 2 auf ein Objekt abgebildet wird.

Schauen Sie sich das an Plunk

In der Methode getPersonWithGetProperty erwarte ich die Rückgabe eines Observable vom Typ PersonWithGetProperty. Jedoch! Ich kann nicht auf die Eigenschaft fullName zugreifen. Ich denke, ich müsste eine neue Instanz der Klasse PersonWithGetProperty erstellen und die Antwort auf dieses neue Objekt mithilfe des Klassenkonstruktors zuordnen. Aber wie macht man das in der Methode getPersonWithGetProperty?

import {Injectable} from '@angular/core';
import {Http, Response} from '@angular/http';
import {Observable} from 'rxjs/Rx';

export class PersonWithGetProperty {
  constructor(public firstName: string, public lastName: string){}

  get fullName(): string {
    return this.firstName + ' ' + this.lastName;
  }
}

@Injectable()
export class PersonService {
    constructor(private http: Http) {
    }

    getPersonWithGetProperty(): Observable<PersonWithGetProperty> {
        return this.http.get('data/person.json')
         .map((response: Response) => <PersonWithGetProperty>(response.json()));
    }
}
16

Das Problem ist, dass Sie den analysierten JSON-Code zwingen, sich wie die Klasse zu verhalten.

Anwenden der <PersonWithGetProperty> erstellt eigentlich keine neue Instanz von PersonWithGetProperty, sondern weist den Compiler nur an, die Klappe zu halten, weil Sie wissen, was Sie tun. Wenn Sie eine Instanz PersonWithGetProperty erstellen möchten, müssen Sie sie mit new erstellen.

Glücklicherweise sind Sie schon auf halbem Weg, fügen Sie einfach ein weiteres map hinzu, nachdem Sie die Ausgabe analysiert haben:

@Injectable()
export class PersonService {
    constructor(private http: Http) {
    }

    getPersonWithGetProperty(): Observable<PersonWithGetProperty> {
        return this.http.get('data/person.json')
         .map((response: Response) => response.json())
         .map(({firstName, lastName}) => new PersonWithGetProperty(firstName, lastName));
    }
}

Bearbeiten

Damit dies funktioniert, müssen Sie sicherstellen, dass Sie RxJS 5 verwenden:

import 'rxjs/add/operator/map'

Wenn Sie zukünftige Sicherheit wünschen, sollten Sie die in späteren Versionen von RxJS 5 eingeführte pipe -Syntax verwenden

// Either
import {map} from 'rxjs/operators'

return this.http.get('data/person.json').pipe(
  map((response: Response) => response.json()),
  map(({firstName, lastName}) => new PersonWithGetProperty(firstName, lastName))
);
26
paulpdaniels