How to return value inside subscribe Angular 4

给你一囗甜甜゛ 提交于 2020-01-01 04:04:28

问题


I'm new to observables in angular. I have a problem wanting to return a value inside a subscribe method. I have the following method (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;
}

the firts console.log(totalQuestions) print 4 but the second console.log(totalQuestions) print undefined. I understand that subscribe is an asynchronous operation and that for that reason the second console.log(totalQuestions) ("In order to write the code") print undefined, but I can not find the way to return the variable after the subscribe method has been completed. Now, if I change the subscribe to 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;
}

the firts console.log(totalQuestions) does not print anything and the second console.log(totalQuestions) print undefined. It's something that I do not understand because it happens.

I hope you can help me clarify the concept that I do not understand. Thanks!


回答1:


You can't directly return totalQuestions like that, you need to use a subject to achieve that.

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))




回答2:


Observable runs when you subscribe to it and what return from subscription is always a subscription object like setInterval. first sample: beacause this is a async call, second console.log won't wait for subcribe to finish before it excutes.

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)



回答3:


I made a live example. You do not need to fire the subscription to make transformations to the array or reduce some object to a single value, here is my approached. Your 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));
}

Your component

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


来源:https://stackoverflow.com/questions/49605090/how-to-return-value-inside-subscribe-angular-4

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!