parse - recorrer json typescript
Angular2 arroja un resultado json a una interfaz (2)
Puede hacer una aserción de tipo a la interfaz que está esperando en el objeto creado por JSON.parse.
this.http.get(''http://localhost:4200/'').subscribe((value: Response) => {
let hero = <ServerInfo>value.json();
});
Sin embargo, esto no generará ningún error si el servidor le envía objetos defectuosos por dos motivos.
En el momento de la compilación, el transpiler no sabe qué enviará el servidor.
En el tiempo de ejecución, toda la información de tipo se borra, ya que todo se compila en javascript.
Utilizando Angular2 y mecanografiado, me han devuelto JSON desde un webApi y necesito incluirlo en una matriz de cierto tipo. No puedo averiguar cómo lanzar el json a la interfaz que necesito.
Mi tipo es esta interfaz:
export interface Country {
Id: number;
Name: string;
}
Mi simulacro devuelve esta matriz:
export var COUNTRIES: Country[] = [
{ "Id": 11, "Name": "US" },
{ "Id": 12, "Name": "England" },
{ "Id": 13, "Name": "Japan" }
];
Aquí está mi código: country.service.ts
@Injectable()
export class CountryService {
private _http = null;
constructor(http: Http) {
this._http = http;
}
getCountries() {
return Promise.resolve(COUNTRIES);
}
}
Entonces lo llamo con esto:
export class CountryPickerComponent {
public countries: Country[];
constructor(private _countryService: CountryService) { }
getCountries() {
this._countryService.getCountries().then(data => this.setData(data));
}
setData(data) {
//this.countries = data;
this.countries = JSON.parse(data);
var q = 1;
}
ngOnInit() {
this.getCountries();
}
}
Como puede ver, tengo una variable de clase llamada países que es una matriz de la interfaz de país. Esto funciona como se esperaba. (Sé que no necesito ese método setData - es para depurar)
A continuación, cambié el servicio a una llamada wepApi que devuelve este json.
"[{"name":"England","id":1},{"name":"France","id":2}]"
Cambié el método getCountries en el servicio para:
getCountries() {
return new Promise(resolve=>
this._http.get(''http://localhost:63651/Api/membercountry'')
.subscribe(data => resolve(data.json()))
);
}
Usando JSON.parse, lo convierto a una matriz que luego puedo usar en angular2. Funciona. Crea la matriz con los datos. Pero no es una matriz que implementa la interfaz de país.
Observe que los nombres de campo del JSON están en minúsculas, pero las propiedades de la interfaz comienzan con una mayúscula y codifico a la interfaz. Como resultado, cuando obtuve el json real no funcionó. ¿Hay una manera de ''lanzar'' esto a la interfaz, lo que debería arrojar un error y hacerme saber que algo está mal?
Muchos ejemplos usan el mapa en el get como se muestra a continuación:
getCountries() {
var retVal;
return new Promise(resolve=>
this._http.get(''http://localhost:63651/Api/membercountry'')
.map(ref => ref.json())
.subscribe(data => resolve(data.json()))
);
}
No puedo encontrar documentación sobre esto. Cuando lo intento nunca obtengo datos pero no hay error. No hay error de compilación y no hay error de tiempo de ejecución.
Viktor Savkin tiene una biblioteca para verificar los tipos de tiempo de ejecución en este tipo de situación, pero no funciona con interfaces porque Typescript no exporta información de tiempo de ejecución a las interfaces. Hay una discusión sobre esto here .
Hay dos soluciones posibles:
- Si sabe que los datos provenientes de la API son la forma correcta, y solo está buscando darle a su IDE / al compilador información sobre esta forma, puede emitir según la respuesta de toskv.
- Si no está seguro de la API y desea que su aplicación se lance si los datos tienen la forma incorrecta, tendrá que implementar su propio control. Esto es un poco elevado, pero vale la pena para aplicaciones más grandes.
En general, veo los tipos de Typescript como compiladores más que un sistema de tipo riguroso: después de todo, tiene que compilarse en un lenguaje sin tipo.