2016-06-23 20 views
5

Sto costruendo la mia prima app Angular 2 e sto riscontrando problemi nel concatenare gli abbonati osservabili.Angular 2 - concatenamento degli abbonati osservabili

Il seguente codice funziona bene in Chrome ma non in Firefox e IE.

Qual è il modo corretto di fare quanto segue? Ho bisogno di ottenere la posizione corrente dell'utente quindi passare questo in una seconda chiamata (getTiles).

Non vedo alcun errore negli strumenti del browser web dev. Questo è anche quando corro su localhost. Il sito non è ancora stato distribuito. Non sono sicuro se questo potrebbe essere correlato.

Sto usando Angular 2.0.0-rc.2.

ngOnInit(): void { 

     this._LocationService.getLocation().subscribe(
      location => {this.location = location; 

        // make the next call using the result of the first observable 
        this._TilesService.getTiles(0, location).subscribe(
         tiles => {this.tiles = tiles; this.index = 1;}, 
         error => this.errorMessage = <any>error);     
      });  
} 

Ecco il servizio di localizzazione ...

import { Injectable } from '@angular/core'; 
import { Observable } from 'rxjs/Observable'; 
import { Observer } from 'rxjs/Observer'; 

import { ILocation } from '../interfaces/location'; 

@Injectable() 
export class LocationService { 

    constructor() { } 

    getLocation(): Observable<ILocation> { 

     let locationObservable = new Observable<ILocation>((observer: Observer<ILocation>) => { 

      if (navigator.geolocation) { 

       var positionOptions = { 
        enableHighAccuracy: false, 
        timeout: 1000, 
        maximumAge: 5000 
       }; 

       navigator.geolocation.getCurrentPosition(function (position) { 

        var location: ILocation = { 
         Longitude: position.coords.longitude, 
         Latitude: position.coords.latitude 
        }; 

        observer.next(location); 
       }, this.locationErrorHandler, positionOptions); 
      } 
     }); 

     return locationObservable; 
    } 

    locationErrorHandler(error:any) { } 
} 

Ecco il servizio getTiles ...

import { Injectable } from '@angular/core'; 
import { Http, Response } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 

import { ITile } from '../interfaces/tile'; 
import { ILocation } from '../interfaces/location'; 

@Injectable() 
export class TilesService { 

    constructor(private _http: Http) { } 

    getTiles(index: number, location: ILocation): Observable<ITile[]> { 
     this._tileUrl = 'SOME URL'; 

     return this._http.get(this._tileUrl) 
      .map((response: Response) => <ITile[]> response.json()) 
      .catch(this.handleError); 
    } 

    private handleError(error: Response) { 
     console.error(error); 
     return Observable.throw(error.json().error || 'Server error'); 
    } 
} 
+0

Questo codice sembra corretto. Che cosa c'è che non va? Forniscici il codice di 'getLocation' e' getTiles' –

+0

Sto facendo qualcosa di simile nella mia app Angular 2 rc2 e funziona su tutti i browser. Suggerirei di usare una forte digitazione ovunque. Mi rende sicuramente più facile la vita. – hholtij

+0

Ho pubblicato i servizi getLocation e getTiles. –

risposta

4

il codice sia corretto, ma nel tuo caso si può evitare la nidificazione abbonamenti facendo questo ...

ngOnInit(): void { 

    this._LocationService.getLocation().concatMap(location => { 
     this.location = location; 

     // make the next call using the result of the first observable 
     return this._TilesService.getTiles(0, location);  
    }).subscribe(
     tiles => {this.tiles = tiles; this.index = 1;}, 
     error => this.errorMessage = <any>error);     
} 

concatMap (RxJS 5) è selectConcat in RxJS 4 secondo https://github.com/ReactiveX/rxjs/blob/master/MIGRATION.md, non ho usato RxJS 4 anche se