web-dev-qa-db-fra.com

Comment retourner une valeur dans subscribe Angular 4

Je suis nouveau aux observables en angulaire. J'ai un problème à vouloir renvoyer une valeur dans une méthode subscribe. J'ai La méthode suivante (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;
}

les premiers console.log(totalQuestions) print 4 mais le second console.log(totalQuestions) print undefined . Je comprends que subscribe est une opération asynchrone et que, pour cette raison, la deuxième console.log(totalQuestions) ("afin d’écrire le code") affiche undefined, mais je ne trouve pas le moyen de renvoyer la variable une fois la méthode subscribe complétée. . Maintenant, si je change d'abonnement en map:

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;
}

la première console.log(totalQuestions) n'imprime rien et la seconde console.log(totalQuestions) imprime non définie. C'est quelque chose que je ne comprends pas parce que ça arrive.

J'espère que vous pourrez m'aider à clarifier le concept que je ne comprends pas. Merci!

4
AlejoDev

Vous ne pouvez pas retourner directement total Questions comme cela, vous devez utiliser un sujet pour y parvenir.

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();
}

utilisation: getTotal Question (inForm) .subscribe ((r) => console.log (r))

6
Rajani Kanth

Observable s'exécute lorsque vous vous y abonnez et quel retour d'abonnement est toujours un objet d'abonnement tel que setInterval. premier exemple: comme il s'agit d'un appel asynchrone, le deuxième fichier console.log n'attendra pas la fin de la souscription avant son exécution. 

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

J'ai créé un exemple en direct . Il n'est pas nécessaire de déclencher l'abonnement pour effectuer des transformations dans le tableau ou réduire un objet à une valeur unique, voici mon approche .....Votre 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));
}

Votre composant

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