wake-up-neo.com

Wie kann ich den Wert innerhalb von Subscribe Angular 4 zurückgeben?

Ich bin neu in Observables in Winkel. Ich habe ein Problem damit, einen Wert innerhalb einer subscribe-Methode zurückzugeben. Ich habe die folgende Methode (getFirebaseData(idForm:string):observable <any[]>):

getTotalQuestions(idForm:string){
let totalQuestions:number;
this.getFirebaseData(idForm+"/Metadatos")
.subscribe(items => 
  {
    items.map(item => {
      totalQuestions=item.Total;
      console.log(totalQuestions);
    });
  }
);
console.log(totalQuestions);
return totalQuestions;
}

die ersten console.log(totalQuestions) print 4 aber die zweite console.log(totalQuestions) print undefined . Ich verstehe, dass subscribe eine asynchrone Operation ist und aus diesem Grund die zweite console.log(totalQuestions) ("Um den Code zu schreiben") undefined druckt, aber ich finde keinen Weg, die Variable zurückzugeben, nachdem die subscribe-Methode abgeschlossen wurde . Nun, wenn ich die Karte zu Abonnieren ändere:

getTotalQuestions(idForm:string){
let totalQuestions:number;
this.getFirebaseData(idForm+"/Metadatos")
.subscribe(items => 
  {
    items.map(item => {
      totalQuestions=item.Total;
      console.log(totalQuestions);
    });
  }
);
console.log(totalQuestions);
return totalQuestions;
}

die Vorgänge console.log(totalQuestions) druckt nichts und die zweite console.log(totalQuestions) druckt nicht definiert. Ich verstehe das nicht, weil es passiert.

Ich hoffe, Sie können mir helfen, das Konzept zu klären, das ich nicht verstehe. Vielen Dank!

4
AlejoDev

Sie können totalQuestions nicht direkt zurückgeben. Um dies zu erreichen, müssen Sie einen Betreff verwenden.

getTotalQuestions(idForm:string) : Observable<string>{
let totalQuestions:number;
var subject = new Subject<string>();
this.getFirebaseData(idForm+"/Metadatos")
.subscribe(items => 
  {
    items.map(item => {

      totalQuestions=item.Total;
      console.log(totalQuestions);
      subject.next(totalQuestions);
    });
  }
);
  return subject.asObservable();
}

usage: getTotalQuestion (idForm) .subscribe ((r) => console.log (r))

6
Rajani Kanth

Observable wird ausgeführt, wenn Sie es abonnieren und was von der Subskription zurückgegeben wird, ist immer ein Subskriptionsobjekt wie setInterval. Erstes Beispiel: Da dies ein asynchroner Aufruf ist, wartet second Console.log nicht, bis der Vorgang abgeschlossen ist, bevor der Befehl beendet wird. 

getTotalQuestions(idForm:string){
let totalQuestions:number;
this.getFirebaseData(idForm+"/Metadatos")
 .map(items => 
     items.map(item => {
     totalQuestions=item.Total;
     console.log(totalQuestions);
  });
)
}
getTotalQuestion('231').subscribe(console.log)
2
Fan Cheung

Ich habe ein Live-Beispiel erstellt . Sie müssen das Abonnement nicht feuern, um das Array zu transformieren oder ein Objekt auf einen einzigen Wert zu reduzieren. Hier ist mein Ansatz .Ihr Service

getTotalQuestions(idForm: string): Observable<any> {
    return this.getFirebaseData(`${idForm}/Metadatos`)
        .pipe(map(items => items
            .map(item => item.Total)
            .reduce((a, b) => a+b), 0));
}

Ihre Komponente

this.service.getTotalQuestions('id')
    .subscribe(totalQuestions => console.log(totalQuestions));
0
Luillyfe