webentwicklung-frage-antwort-db.com.de

Angular 2 - Daten direkt von einem Observable zurückgeben

Ich habe mit dem Kopf gegen diesen gestoßen, um es herauszufinden, und keine Menge an Dokumentation, die ich lesen konnte, hat mir eine Antwort auf meine Frage gegeben.

Ich habe einen Dienst, der direkt mit einer API spricht und ein beobachtbares Ereignis zurückgibt, das ich unter normalen Umständen abonnieren und mit den Daten tun würde, was ich will, jedoch in einem sekundären Dienst, der die Anforderungen des erholsamen Dienstes verwendet, muss ich dies tun in der Lage sein, Werte aus der Anfrage zurückzugeben.

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

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

Im obigen Beispiel möchte ich wissen, ob es eine Möglichkeit gibt, res von getSomething() innerhalb von returnSomething() zurückzugeben. Wenn es auf diese Weise nicht erreichbar ist, was ist die Alternative? Ich werde hinzufügen, dass der _restService ziemlich stark von ihm abhängig ist und ich nicht wirklich damit anfangen möchte.

29
Sidriel

Da http-Aufrufe und dergleichen asynchron sind, wird anstelle eines synchronen Wertes ein Observable zurückgegeben. Sie müssen es abonnieren, und im Rückruf dort erhalten Sie die Daten. Daran führt kein Weg vorbei.

Eine Möglichkeit wäre, Ihre Logik in den subscribe -Aufruf einzufügen

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

Aber ich mache es gerne, indem ich einen Rückruf hinzufüge, die Logik von außen einspeise (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);
});
42
rinukkusu

Ich habe das selbst nicht benutzt, aber ich glaube, es sollte theoretisch 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));
}

Überprüfen Sie Betreff docs für weitere Informationen. Sie können verschiedene Arten von Betreffs verwenden, z. B. BehaviorSubject hat die Eigenschaft value, auf die Sie zugreifen können ...

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

Hier ist der funktionierender Plunker ...

1
Sasxa

Ich hatte ein ähnliches Problem. Meine Lösung bestand darin, das Observable mit .toPromise () in ein Versprechen umzuwandeln (und async zu verwenden - warten Sie darauf, es zurückzugeben und Fehler abzufangen). Sie können Ihren Code in Folgendes konvertieren:

 async getSomething() {
     try{
         return await this._restService.addRequest('object', 'method').run().toPromise()
      } catch (err){
       console.error(err);
          }
  }
0
hjbello