web-dev-qa-db-fra.com

Comment mapper une réponse de http.get à une nouvelle instance d'un objet tapé dans Angular 2

J'essaie de comprendre comment mapper le résultat d'un appel de service à un objet à l'aide de http.get et Observables dans Angular 2.

Jetez un oeil à cela Plunk

Dans la méthode getPersonWithGetProperty, je m'attends à retourner un observable de type PersonWithGetProperty. Toutefois! Je ne peux pas accéder à la propriété fullName. Je suppose que je devrais créer une nouvelle instance de la classe PersonWithGetProperty et mapper la réponse à ce nouvel objet en utilisant le constructeur de classe. Mais comment faites-vous cela dans la méthode 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

Le problème est que vous contraignez le json analysé à se comporter comme la classe.

Appliquer le <PersonWithGetProperty> ne crée pas réellement une nouvelle instance de PersonWithGetProperty, il dit simplement au compilateur de se fermer car vous savez ce que vous faites. Si vous souhaitez réellement créer une instance PersonWithGetProperty, vous devez la construire avec new.

Heureusement, vous êtes déjà à mi-chemin, ajoutez simplement un autre map après avoir analysé la sortie:

@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));
    }
}

Modifier

Pour que cela fonctionne, vous devez vous assurer que vous utilisez pour RxJS 5:

import 'rxjs/add/operator/map'

Si vous souhaitez une sécurité future, vous devez utiliser la syntaxe pipe introduite dans les versions ultérieures de RxJS 5

// 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