2016-06-16 14 views
16

Ich habe meinen Kopf gegen diesen Versuch geschlagen, es herauszufinden, und keine Menge von Dokumentation, die ich lesen konnte, hat mir eine Antwort auf meine Frage gegeben.Angular 2 - Liefern Daten direkt von einem Observable

Ich habe einen Dienst, der direkt zu einer API spricht und ein beobachtbares Ereignis zurücksendet, das ich unter normalen Umständen abonnieren und tun würde, was ich mit den Daten will, jedoch in einem sekundären Dienst, der die Anfragen vom erholsamen Dienst verwendet Ich muss Werte aus der Anfrage zurückgeben können.

getSomething() { 
    return this._restService.addRequest('object', 'method').run() 
     .subscribe(
      res => { 
       res; 
      }, 
      err => { 
       console.error(err); 
      } 
     ); 
} 

returnSomething() { 
    return this.getSomething(); 
} 

Im schnellen Beispiel oben, ich möchte wissen, ob es einen Weg gibt, ich res von getSomething() innerhalb returnSomething() zurückkehren kann. Wenn es auf diese Weise nicht möglich ist, was ist die Alternative? Ich werde hinzufügen, dass der _restService ziemlich stark darauf angewiesen ist und ich nicht wirklich damit anfangen will.

+0

Wo Sie verwenden 'returnSomething()'? Sie wissen, dass dies ein asynchroner Vorgang ist, so dass Sie das Ergebnis nicht sofort "erhalten" können. Sie können vielleicht die '(res)' innerhalb von subscribe in 'returnSomething()' zurückgeben, aber ich weiß nicht, ob es praktisch wäre. – echonax

+0

Das obige Beispiel wäre in einem Service enthalten, und der Aufruf der Methode würde aus mehreren Komponenten bestehen, weshalb ich nur den 'res' Wert zurückgeben möchte, da es ziemlich viel Code sparen würde. Ich müsste auch in der Lage sein, die Ergebnisse von zwei oder mehr ähnlichen Methoden zu vergleichen. – Sidriel

Antwort

29

Da HTTP-Aufrufe und ähnliche async sind, erhalten Sie Observable anstelle eines synchronen Werts zurückgegeben. Sie müssen es abonnieren und im Callback erhalten Sie die Daten. Es gibt keinen Weg dahin.

Eine Möglichkeit wäre, Ihre Logik zu versetzen, in dem subscribe Anruf

getSomething() { 
    return this._restService.addRequest('object', 'method').run() 
     .subscribe(
      res => { 
       // do something here 
       res; 
      }, 
      err => { 
       console.error(err); 
      } 
     ); 
} 

Aber die Art, wie ich es gern tun, ist einen Rückruf an, von außerhalb der Logik zu injizieren (vielleicht eine Komponente, vielleicht ein anderer Dienst):

getSomething(callback: (data) => void) { 
    return this._restService.addRequest('object', 'method').run() 
     .subscribe(
      res => { 
       callback(res); 
      }, 
      err => { 
       console.error(err); 
      } 
     ); 
} 

und in Ihrer Komponente oder wo auch immer:

this._yourService.getSomething((data) => { 
    // do something here 
    console.log(data); 
}); 
+3

Definitiv eine neue Art, über die Nutzung von Diensten nachzudenken, dies entpuppte sich als genau das, was benötigt wurde! – Sidriel

+1

Ich bin hier vermutlich wegen des Observable-Keywords gelandet. Ich muss etwas Ähnliches tun. Welche Art von Service hat eine Methode .run()? Ich kann das nicht auf einem normalen Angular 2 http-Dienst verwenden. thx –

1

Ich habe das nicht selbst verwenden, aber ich glaube, es sollte in der Theorie funktionieren (:

// service.ts 
getSomething() { 
    let subject: Subject = new Subject(); 
    this._restService.addRequest('object', 'method').run() 
    .subscribe(subject); 
    return subject; 
} 

// this can be removed (; 
returnSomething() { 
    return this.getSomething(); 
} 

// component.ts 
ngOnInit() { 
    this.service.returnSomething() 
    .subscribe(res => console.log(res), err => console.log(err)); 
} 

prüft subject docs für weitere Informationen. Sie können verschiedene Arten von Subjekt, zum Beispiel BehaviorSubjectvalue Eigenschaft haben können Sie auf ...

ngOnInit() { 
    // if you use BehaviorSubject 
    this.service.returnSomething().value 
} 

Hier ist die working plunker ...

+0

Dies wird nicht funktionieren, da Betreff zurückgegeben wird, bevor Sie die Daten von Abonnieren erhalten. – rinukkusu

+0

@rinukkusu True, für den Anfangswert, sollte nach funktionieren .. Sie können den Anfangswert für * BehaviourSubject * tho '... oder '.filter (Boolean)' vor dem Abonnieren der beobachtbaren ... – Sasxa

+0

@rinukkusu Ich habe Plunker Link mit Arbeitsbeispiel hinzugefügt ... – Sasxa

Verwandte Themen