Obtener un «objeto TS» en vez del Json tras un http


#1

Buenas.

Tengo un problema «medio solucionado». Y es que cuando con HTTP te llega un response y haces el típico

let data = response.json() as User[];

Data es un array de objetos JSON, no de objetos User. Si tienes bien sincronizado la respuesta con la interfaz User deberían ser iguales, pero si tienes metodos estos no están.

Lo único que he encontrado es https://www.npmjs.com/package/serializer.ts

Que medio me hace la transformación. El problema que solo me «serializa» el objeto «padre», los sub objetos no. Se supone que usando @Type() pero en cuanto los pongo Angular explota…

¿Conocéis alguna fórmula más bonita, elegante o al menos eficaz?


#2

No sé si solucionará tu problema de nested objects (has pensado en “componentizar” esos subobjetos?), pero habitualmente el fetch de datos se hace con observables y .map() de RxJS

import { Injectable }              from '@angular/core';
import { Http, Response }          from '@angular/http';
 
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
 
import { Hero } from './hero';
 
@Injectable()
export class HeroService {
  private heroesUrl = 'api/heroes';  // URL to web API
 
  constructor (private http: Http) {}
 
  getHeroes(): Observable<Hero[]> {
    return this.http.get(this.heroesUrl)
                    .map(this.extractData)
                    .catch(this.handleError);
  }

...

https://angular.io/guide/http

Aquí un post de scotch.io donde hablan del tema con un plunkr bastante apañado: https://scotch.io/tutorials/angular-2-http-requests-with-observables

Ojalá te sirva!


#3

Se agradece, pero esa no era la duda.

El problema es que si tengo

export class Hero {
   name: string;
   nickname: string;

  getFullName() : string {
     return `${this.name}, the ${this.nickname}`
  }
}

Cuando objeta un JSON con

{ name: "Super López", nickname: "The True Hero" }

E intente llamar a getFullName() voy a encontrarme un precioso undefined, pues el JSON no es un «objeto Hero», solo tiene mismos atributos.


#4

Quizás deberías crearte un constructor que parsee el objeto JSON que le pases y lo asigne a los miembros de la clase. Te va a dar más seguridad en cuanto a la conversión y mayor control.


#5

Esa era la opción «a mano», pero es que me da una pereza terrible tener que mapear todos los atributos…


#6

No seas perezoso. Todo sea por la consistencia de tu aplicación. :wink:


#7

Por lo que veo, la 4.3 trae algo llamado «typed response»

commit Angular 4.3

Y hay métodos como put, get…

¿Quizás sea lo que estoy pidiendo?


#8

Parece que no hay una format “estándar” de serializar objetos javascript.

Igual te sirve esta librería:

Edit: por lo visto no, ya que no serializa funciones!


#9

Serialize.ts ha evolucionado a class-transformer y ahora funciona perfectamente con los types y todo.