2017-09-29 1 views
1

J'ai travaillé dans la plupart des héros tutoriel et ont décidé d'ajouter un Tracker Hero qui affiche une carte avec l'emplacement du héros là-dessus.Propriété de Observable est vide

Cela a fonctionné lorsque les valeurs ont été moquaient dans une constante, mais maintenant j'appelle un service de repos et la propriété Emplacement est vide. Je suis sûr que j'ai juste mal écrit cela et pourrait utiliser de l'aide avec la syntaxe.

Voici le composant carte du héros:

import 'rxjs/add/operator/switchMap'; 
import { Observable } from 'rxjs/Observable'; 
import { Component, OnInit, NgZone } from '@angular/core'; 
import { ActivatedRoute, Router, ParamMap } from '@angular/router'; 

import { Hero, HeroService } from '../heroes/hero.service'; 
import { HeroLocationService } from './hero-location.service'; 
import { HeroLocation } from './hero-location'; 

@Component({ 
    template: ` 
    <style> 
     agm-map { 
      height: 300px; 
      width: 400px; 
     } 
    </style> 
    <h2>HERO MAP</h2> 
     <div *ngIf="hero$ | async as hero"> 
     <h3>{{ hero.HeroName }}'s location is {{ hero.Location }}</h3> 
      <div *ngIf="loc$ | async as loc"> 
       <h4>Latitude: {{ loc.lat() }} Longitude: {{ loc.lng() }}</h4> 
       <agm-map [latitude]="loc.lat()" [longitude]="loc.lng()"> 
        <agm-marker [latitude]="loc.lat()" [longitude]="loc.lng()"></agm-marker> 
       </agm-map> 
      </div> 
     <p> 
      <button (click)="gotoHeroes(hero)">Back</button> 
     </p> 
     </div> 
    ` 
}) 
export class HeroMapComponent implements OnInit { 
    hero$: Observable<Hero>; 
    loc$: Observable<any>; 

    constructor(
    private service: HeroService, 
    private router: Router, 
    private route: ActivatedRoute, 
    private locationservice: HeroLocationService 
) {} 

    ngOnInit() { 

     var hloc: string; 

     //the problem is here ////////////////////////////////////// 
     this.hero$ = this.route.paramMap 
      .switchMap((params: ParamMap) =>    
       this.service.getHero(params.get('id'))); 

     this.hero$.subscribe(function (z) { 
      hloc = z.Location.toString(); 
     }); 
     //////////////////////////////////////////////// 

     this.loc$ = this.locationservice.getGeocoding(hloc); 
    } 

    gotoHeroes(hero: Hero) { 
     let heroId = hero ? hero.Id : null; 

     // Pass along the hero id if available 
     // so that the HeroList component can select that hero. 
     // Include a junk 'foo' property for fun. 

     this.router.navigate(['/hero-tracker', { id: heroId, foo: 'foo' }]); 
    } 
} 

Je peux voir dans l'onglet Réseau de Chrome que les données sont renvoyées correctement:

{"Id":11,"HeroName":"Batman","Location":"Chicago, Illinois"} 

Le hero.service ressemble à ceci:

import 'rxjs/add/observable/of'; 
import 'rxjs/add/operator/map'; 
import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Rx'; 

import { HttpClient } from '@angular/common/http'; 

export class Hero { 
    constructor(public Id: number, public HeroName: string, public Location: string) { } 
} 

@Injectable() 
export class HeroService { 

    constructor(private http: HttpClient) { } 

    getHeroes(): Observable<Hero[]> { 
     return this.http.get<Hero[]>('http://localhost:50125/api/heroes') 
      .catch(error => Observable.throw(error)); 
    } 

    getHero(id: number | string): Observable<Hero> { 
     return this.http.get<Hero>('http://localhost:50125/api/heroes/' + id) 
      .catch(error => Observable.throw(error)); 
    } 

} 

Répondre

2

Je crois que votre question tente d'utiliser l'emplacement avant qu'il ne soit en fait à partir du serveur.

essayez ceci:

 this.hero$.subscribe(z => { 
      hloc = z.Location.toString(); 
      this.loc$ = this.locationservice.getGeocoding(hloc); 
     }); 

Hloc est défini dans le rappel, mais est utilisé en dehors de la souscription, qui est une opération asynchrone. En l'utilisant uniquement lorsque hloc est défini, vous pouvez vous assurer qu'il aura la même valeur que le serveur retourné.

+0

@TrevorBrooks heureux de vous aider. Si cela répond suffisamment à votre question, acceptez-la pour aider les autres à l'avenir. – rjustin

+0

Fait! Merci encore! – TrevorBrooks