2017-08-07 3 views
0

Ich versuche, den Wert erhalten von http Anfrage an eine lokale deklarieren Variable userLat & userLng und Zugriff auf die Variablen von einer anderen Funktion, aber bekommen undefined als Ergebnis. Die userLat & userLng wurde erfolgreich abgerufen. Versucht mit return this.userLat & this.userLng aber fehlgeschlagen, bitte weisen Sie darauf hin, wenn ich einen Fehler mache.Wie übergibt man den Wert von Funktion zu Funktion?

Zuvor mit der Verwendung arbeiten versprochen. Hatte viele Kopfschmerzen. Gibt es eine einfachere Möglichkeit, die Daten zu erhalten?

Jede Hilfe und Vorschläge sind willkommen. Vielen Dank im Voraus :)

map.ts

export class GoogleMapsProvider { 

userLat:any; 
userLng:any; 

constructor(
public http: Http, 
) { 
} 

load(){ 
    this.http.post() 
    .map(res => res.json()) 
    .subscribe(data => 
    { 
     this.userDetails = data[0]; 

     this.userLat = this.userDetails.ListerLat; 
     this.userLng = this.userDetails.ListerLng; 

     console.log(this.userLat); // successfully return userLat 
     console.log(this.userLng); // successfully return userLng 

    //tried return this.userLat & this.userLng 

    } 
} 


calculate(locations) { 

    console.log(this.userLat); //returned undefined 
    console.log(this.userLng); //returned undefined 

    let usersLocation = { 
    lat: this.userLat, 
    lng: this.userLng 
}; 

} 

mit Versprechen

load(){ 

    if(this.data){ 
     return Promise.resolve(this.data); 
    } 

    return new Promise(resolve => { 

     this.http.get('../example.json').map(res => res.json()).subscribe(data => { 

this.data = data; 

      resolve(this.data); 
     }); 

    }); 

} 
+2

Und wie nennst du 'calculate' Funktion? – MysterX

+0

ok. Das tut mir leid. Wird in Zukunft Notiz nehmen. Ich habe die 'calculate' Funktion in einer anderen Funktion aufgerufen. Zuvor arbeitete ich mit hardcoded 'userLat & userLng' es funktioniert gut. Jetzt möchte ich es auf dynamische Daten anwenden. – aaa

+1

Das scheint mir ein Problem mit dem Oszilloskop zu sein, Sie sollten es verwenden, lassen Sie _self = das; in Ihrer Lademethode. Und dann userLng über _self.userLng = value; – user3492940

Antwort

3

Was können Sie tun, hier ist ein beobachtbares Strom erzeugen Ihre geografische Breite und Länge enthält, und abonnieren dazu in Ihrer Rechenfunktion. Das bedeutet, dass Sie in Ihrer Geschäftslogik nie calculate aufrufen, sondern nur einmal, wenn Ihr Dienst instanziiert wird.

Jedes Mal, wenn Daten von der load Methode zurückkommen, wird Ihre calculate Logik ausgelöst. Sie können darauf vertrauen, dass dies immer dann geschieht, wenn Sie eine Antwort von Ihrem Server erhalten und Sie den Berechnungsaufruf nicht selbst verwalten müssen.

So ein paar Dinge:

  • Entfernen Sie die Breite/Länge Eigenschaften von Ihrem Service.
  • einen beobachtbaren Strom erstellen, der die beiden Werte (Breite/Länge)
  • Abonnieren Sie diesen Stream sofort enthalten, so jederzeit Ihre load Funktionswerte in den Stream hinzufügt, werden Berechnungen durchgeführt werden.

Ihr Service kann wie folgt aussehen:

import { ReplaySubject } from 'rxjs/ReplaySubject'; 

export interface Location { 
    latitude: number; 
    longitude: number; 
} 

export class GoogleMapsProvider { 
    private locationStream: ReplaySubject<Location> = new ReplaySubject(); 

    constructor(public http: Http) { 
     // Subscribes to the location observable stream. 
     this.calculate(); 
    } 

    load(){ 
     this.http.post() 
      .map(res => res.json()) 
      .subscribe(data => { 
       this.userDetails = data[0]; 

       // This will add the location values to the stream. 
       this.locationStream.next({ 
        latitude: this.userDetails.ListerLat, 
        longitude: this.userDetails.ListerLon 
       }); 
      }); 
    } 


    calculate() { 
     // Any time the `load` adds values to the stream, the subscribe callback will be triggered. 
     this.locationStream.asObservable().subscribe((location: Location) => { 
      // Do some calculations using location.latitude and location.longitude 
     }); 
    } 
} 

Wenn Sie den Ansatz nicht wie ein beobachtbares Strom verwenden, können Sie diese noch erreichen können Ihre calculate Funktion rein, indem sie.

So anstelle von this.userLat und this.userLon Zugriff, übergeben Sie in der Lage Objekt, so dass die Funktion calculate rein aus seinen Eingängen geht - auf diese Weise kann es keine undefinierten Werte, wenn Sie sicherstellen, dass nur Sie calculate mit definierten Werten nennen .

Das einzige Problem mit diesem Ansatz ist jedoch, dass Sie nicht calculate von außerhalb Ihrer load Methode, ohne dass die calculate Methode einer unreine Funktion aufrufen können. Und ich rate davon ab, zu versuchen, mit den userLat und userLon Eigenschaften in Ihrem Dienst Zustand zu halten, da das schwer zu debuggen sein kann, wie die Komplexität wächst.

Trotzdem hier geht:

export interface Location { 
    latitude: number; 
    longitude: number; 
} 

export class GoogleMapsProvider { 
    constructor(public http: Http) {} 

    load() { 
     this.http.post() 
      .map(res => res.json()) 
      .subscribe(data => { 
       this.userDetails = data[0]; 

       // Call `calculate` here and pass in location object. 
       this.calculate({ 
        latitude: this.userDetails.ListerLat, 
        longitude: this.userDetails.ListerLon 
       }); 
      }); 
    } 


    calculate(location: Location) { 
     // Do calculations with location.latitude and location.longitude 
    } 
} 
Verwandte Themen