headers example angular typescript angular-httpclient

headers - httpclient angular 5 example



La propiedad ''json'' no existe en el tipo ''Objeto'' (2)

Estoy tratando de obtener datos a través de REST con 2 HttpClient angular. Estoy siguiendo el tutorial angular aquí https://angular.io/tutorial/toh-pt6 y en la sección de Héroes y HTTP verá este fragmento de código que se utiliza para obtener datos de héroe a través de http.

getHeroes(): Promise<Hero[]> { return this.http.get(this.heroesUrl) .toPromise() .then(response => response.json().data as Hero[]) .catch(this.handleError); }

Y abajo hay una versión similar que escribí en mi aplicación.

fetch(startIndex: number, limit: number): Promise<Order[]> { let url = this.baseUrl + "&startIndex=" + startIndex + "&limit=" + limit; return this.http.get(url) .toPromise() .then(response => response.json().results as Order[]) .catch(this.handleError); }

Estoy usando InteliJ Idea y hay una línea roja en la respuesta a la llamada.json () e incluso cuando intento compilar usando ng build , aparece el error.

La propiedad ''json'' no existe en el tipo ''Objeto''.

Puede observar que en lugar de json().data tengo json().results . Esto se debe a que, de acuerdo con el tutorial, el servidor respondió con un objeto que tiene un campo de data , pero mi propio servidor responde con un objeto que tiene un campo de results . Si recorres un poco el tutorial verás este punto.

Observe la forma de los datos que devuelve el servidor. Este ejemplo particular de API web en memoria devuelve un objeto con una propiedad de datos. Tu API podría devolver algo más. Ajusta el código para que coincida con tu API web.

En un intento de solucionar esto, intenté algo como esto

(response: Response) => response.json().results as Order[]

Cuando hice eso, el método .json () se resolvió pero apareció otro error que

Los resultados de la propiedad no existen en el tipo Promesa

Intenté arreglar eso definiendo una interfaz

interface OrderResponse { orders: Order[]; }

Y modificó la llamada a

.get<OrderResponse>(url)...

Pero eso tampoco funcionó. Otro error apareció

El tipo ''OrderResponse'' no se puede asignar al tipo ''Respuesta''.

Una cosa es que, en el tutorial, utilizaron el módulo de Http de Angular, pero en mi aplicación, estoy usando el nuevo Módulo de HttpClient de Angular, así que quizás sea allí donde se produce el error.

Soy nuevo en Angular 2 y esta es la primera aplicación que estoy creando con ella. Si el código anterior ya no es válido con el nuevo HttpClientModule, agradecería cualquier ayuda sobre cómo lograr lo mismo con el nuevo HttpClientModule.

Encontré preguntas similares La propiedad ''json'' no existe en el tipo ''{}'' y la propiedad no existe en el tipo ''objeto'' pero ninguna de las respuestas me ayudó.

Actualizar

Como los comentarios sugieren, no hay un método .json () en el nuevo HttpClientModule. Todavía apreciaría la ayuda sobre cómo lograr el mismo efecto con el nuevo módulo. De la guía hicieron algo como esto.

http.get<ItemsResponse>(''/api/items'').subscribe(data => { // data is now an instance of type ItemsResponse, so you can do this: this.results = data.results; });

Lo que entiendo perfectamente, pero mi problema es que ese código no está dentro de un componente sino que es un servicio, por lo que llamar a suscribirse y asignar el resultado a un campo de instancia no tendrá mucho sentido.

Necesito mi servicio para devolver una serie de pedidos envueltos en una promesa. Los componentes de mi solo pueden hacer llamadas como

this.orderService.fetch(0, 10).then(orders => this.orders = orders)

También pensé en declarar una variable local en mi método de búsqueda de servicios para poder hacer

.subscribe(data => { this.orders = data.results; } // and out of the get call I return my local variable orders like return Promise.resolve(orders)

Pero eso no tiene mucho sentido para mí, ya que la llamada a .get () es asíncrona y el método puede retornar incluso antes de que se obtengan todos los datos y la matriz de órdenes esté vacía.

Actualizar

Como se solicita aquí es el código para handleError

private handleError(error: any): Promise<any> { console.log(''An error occured '', error); return Promise.reject(error.message || error); }


Suponiendo que su backend devuelve algo como:

[{},{},{},...{}]

ACTUALIZACIÓN: ahora que el backend devuelve {results: [{},{}]}

en formato JSON, donde cada {} es un objeto serializado, necesitaría lo siguiente:

// Somewhere in your src folder export interface Order { // Properties } import { HttpClient, HttpParams } from ''@angular/common/http''; import { Observable } from ''rxjs/Observable''; import ''rxjs/add/operator/catch''; import ''rxjs/add/operator/map''; import { Order } from ''somewhere_in_src''; @Injectable() export class FooService { ctor(private http: HttpClient){} fetch(startIndex: number, limit: number): Observable<Order[]> { let params = new HttpParams(); params = params.set(''startIndex'',startIndex.toString()).set(''limit'',limit.toString()); // base URL should not have ? in it at the en return this.http.get(this.baseUrl,{ params }) .map(res => res.results as Order[] || []); // in case that the property results in the res POJO doesnt exist (res.results returns null) then return empty array ([]) } }

Eliminé la sección de captura, ya que podría archivarse a través de un interceptor HTTP. Revisa los documentos . Como ejemplo:

https://gist.github.com/jotatoledo/765c7f6d8a755613cafca97e83313b90

Y para consumir solo hay que llamarlo así:

// In some component for example this.fooService.fetch(...).subscribe(data => ...); // data is Order[]


Para futuros visitantes : en el nuevo angular.io/guide/http (Angular 4.3+), el objeto de response es JSON de forma predeterminada, por lo que ya no es necesario que realice los datos de response.json().data . Solo usa la response directamente.

Ejemplo (modificado de la documentación oficial):

import { HttpClient } from ''@angular/common/http''; @Component(...) export class YourComponent implements OnInit { // Inject HttpClient into your component or service. constructor(private http: HttpClient) {} ngOnInit(): void { this.http.get(''https://api.github.com/users'') .subscribe(response => console.log(response)); } }

No olvide importarlo e incluir el módulo bajo importaciones en app.module.ts de su proyecto:

... import { HttpClientModule } from ''@angular/common/http''; @NgModule({ imports: [ BrowserModule, // Include it under ''imports'' in your application module after BrowserModule. HttpClientModule, ... ], ...