Solución:
Aquí es donde te equivocaste:
this.result = http.get('friends.json')
.map(response => response.json())
.subscribe(result => this.result =result.json());
debería ser:
http.get('friends.json')
.map(response => response.json())
.subscribe(result => this.result =result);
o
http.get('friends.json')
.subscribe(result => this.result =result.json());
Has cometido dos errores:
1- Asignaste el propio observable a this.result
. Cuando realmente deseaba asignar la lista de amigos a this.result
. La forma correcta de hacerlo es:
-
te suscribes a lo observable.
.subscribe
es la función que realmente ejecuta lo observable. Toma tres parámetros de devolución de llamada de la siguiente manera:.subscribe(success, failure, complete);
por ejemplo:
.subscribe(
function(response) { console.log("Success Response" + response)},
function(error) { console.log("Error happened" + error)},
function() { console.log("the subscription is completed")}
);
Por lo general, toma los resultados de la devolución de llamada exitosa y los asigna a su variable. la devolución de llamada de error se explica por sí misma. la devolución de llamada completa se utiliza para determinar que ha recibido los últimos resultados sin ningún error.
En su plunker, la devolución de llamada completa siempre se llamará después de la devolución de llamada exitosa o de error.
2- El segundo error, llamaste .json()
sobre .map(res => res.json())
, luego lo volvió a llamar en la devolución de llamada exitosa del observable.
.map()
es un transformador que transformará el resultado en lo que sea que devuelvas (en tu caso .json()
) antes de que pase a la devolución de llamada exitosa, debe llamarlo una vez en cualquiera de ellos.
Conceptos
Observables in short aborda el procesamiento y los eventos asincrónicos. En comparación con las promesas, esto podría describirse como observables = promesas + eventos.
Lo bueno de los observables es que son perezosos, se pueden cancelar y se pueden aplicar algunos operadores en ellos (como map
, …). Esto permite manejar cosas asincrónicas de una manera muy flexible.
Una gran muestra que describe mejor el poder de los observables es la forma de conectar una entrada de filtro a una lista filtrada correspondiente. Cuando el usuario ingresa caracteres, la lista se actualiza. Los Observables manejan las solicitudes AJAX correspondientes y cancelan las solicitudes en curso anteriores si se activa otra por un nuevo valor en la entrada. Aquí está el código correspondiente:
this.textValue.valueChanges
.debounceTime(500)
.switchMap(data => this.httpService.getListValues(data))
.subscribe(data => console.log('new list values', data));
(textValue
es el control asociado con la entrada del filtro).
Aquí hay una descripción más amplia de dicho caso de uso: ¿Cómo estar atento a los cambios de forma en Angular 2 ?.
Hay dos grandes presentaciones en AngularConnect 2015 y EggHead:
- Observables vs promesas – https://egghead.io/lessons/rxjs-rxjs-observables-vs-promises
- Creando-un-observable – https://egghead.io/lessons/rxjs-creating-an-observable
- RxJS en profundidad https://www.youtube.com/watch?v=KOOT7BArVHQ
- Flujo de datos de Angular 2: https://www.youtube.com/watch?v=bVI5gGTEQ_U
Christoph Burgdorf también escribió algunas publicaciones de blog excelentes sobre el tema:
- http://blog.ilsttram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html
- http://blog.ilsttram.io/angular/2016/01/06/taking-advantage-of-observables-in-angular2.html
En acción
De hecho, con respecto a su código, mezcló dos enfoques 😉 Aquí están:
-
Maneja lo observable por tu cuenta. En este caso, usted es responsable de llamar al
subscribe
método en el observable y asigne el resultado a un atributo del componente. Luego puede usar este atributo en la vista para iterar sobre la colección:@Component({ template: ` <h1>My Friends</h1> <ul> <li *ngFor="#frnd of result"> {{frnd.name}} is {{frnd.age}} years old. </li> </ul> `, directive:[CORE_DIRECTIVES] }) export class FriendsList implement OnInit, OnDestroy { result:Array<Object>; constructor(http: Http) { } ngOnInit() { this.friendsObservable = http.get('friends.json') .map(response => response.json()) .subscribe(result => this.result = result); } ngOnDestroy() { this.friendsObservable.dispose(); } }
Devoluciones de ambos
get
ymap
Los métodos son lo observable, no el resultado (del mismo modo que con las promesas). -
Dejemos administrar lo observable por la plantilla angular.. También puede aprovechar el
async
pipe para gestionar implícitamente lo observable. En este caso, no es necesario llamar explícitamente alsubscribe
método.@Component({ template: ` <h1>My Friends</h1> <ul> <li *ngFor="#frnd of (result | async)"> {{frnd.name}} is {{frnd.age}} years old. </li> </ul> `, directive:[CORE_DIRECTIVES] }) export class FriendsList implement OnInit { result:Array<Object>; constructor(http: Http) { } ngOnInit() { this.result = http.get('friends.json') .map(response => response.json()); } }
Puede notar que los observables son perezosos. Por lo tanto, la solicitud HTTP correspondiente solo se llamará una vez que un oyente esté adjunto usando el subscribe
método.
También puede notar que el map
El método se usa para extraer el contenido JSON de la respuesta y luego usarlo en el procesamiento observable.
Espero que esto te ayude, Thierry
import { HttpClientModule } from '@angular/common/http';
La API de HttpClient se introdujo en la versión 4.3.0. Es una evolución de la API HTTP existente y tiene su propio paquete @ angular / common / http. Uno de los cambios más notables es que ahora el objeto de respuesta es un JSON de forma predeterminada, por lo que ya no es necesario analizarlo con el método de mapa.
http.get('friends.json').subscribe(result => this.result =result);