0

I am trying to return value to this.voucherDetails using subscribe but it doesn't seem to work.

Following is the request to the function getVoucherDetails which has the subscribe function.

voucherIDs: string[];
voucherDetails: Promise<any>[];

this.voucherIDs = ['JV-2005-50','JV-2005-40','JV-2005-30'];
this.voucherDetails = this.voucherIDs
.map(id => this.getVoucherDetails(id));
Promise.all(this.voucherDetails)
      .then(() => this.printService.onDataReady());

Following is the function with subscribe to userService which gets data from database.

getVoucherDetails(voucherid) {
    var splitvoucher = voucherid.split('-');
    var vouchertype = splitvoucher[0];
    var vouchermy = splitvoucher[1];
    var voucherno = splitvoucher[2];
    var vouchernotopass = vouchermy+"-"+voucherno;

    var voucherdate;
    var enteries;

    this.userService.getVoucher(vouchernotopass,vouchertype).subscribe(
        res => {
          voucherdate = res['voucherdate'];
          enteries = res['enteries'];
          return { "vouchertype":vouchertype, "vouchernumber": vouchernotopass, "voucherdate": voucherdate, "enteries":enteries};   
        }
    );       
}

But it returns undefined. After going through several posts I have come to understand that you can't return from a .subscribe. But I haven't been able to understand a work around on how to resolve this issue.

1 Answer 1

3

You are working asynchronously with Observable, so you need to use callbacks, like with Promise. You should return an Observable (or Promise) in your method and let the caller subscribe to it:

getVoucherDetails(voucherid) {
    var splitvoucher = voucherid.split('-');
    var vouchertype = splitvoucher[0];
    var vouchermy = splitvoucher[1];
    var voucherno = splitvoucher[2];
    var vouchernotopass = vouchermy+"-"+voucherno;

    var voucherdate;
    var enteries;

    return this.userService.getVoucher(vouchernotopass,vouchertype).pipe(
        map(res => {
          voucherdate = res['voucherdate'];
          enteries = res['enteries'];
          return { "vouchertype":vouchertype, "vouchernumber": vouchernotopass, "voucherdate": voucherdate, "enteries":enteries};   
        })
    );       
}

Use this method like this:

getVoucherDetails(id).subscribe(v => {
  console.log(v.vouchertype);
  console.log(v.vouchernumber);
  console.log(v.voucherdate);
});

In your case:

forkJoin( // forkJoin waits for Observables to complete and then combine last values they emitted.
   this.voucherIDs.map(id => this.getVoucherDetails(id) // array of observable
).subscribe(responses => {
   console.log(responses);
   this.voucherDetails = responses;
});
Sign up to request clarification or add additional context in comments.

7 Comments

thank you for your kind response and my apologies for my limited knowledge. On using getVoucherDetails the way you have suggested, the voucherDetails gets a value of [Subscriber,Subscriber,Subscriber]. How do I get the actual values which were returned by getVoucherDetails and stored in voucherDetails
I just edited my answer add how to use it in your case
I tried adding push in the responses to voucherDetails and it says is not assignable to parameters of type Promise<any>. Tried settings forkJoin = voucherDetails that didn't work either. :(
No, you should assign voucherDetails inside the subscribe. If you want to use Promise + Promise.all: this.voucherDetails = this.voucherIDs.map(id => this.getVoucherDetails(id).toPromise());
Thank you for your patience and all the help. Last thing how do I display this [Object Promise] in html? I tried {{ voucherDetails[0].vouchertype }} and returns [Object Promise]
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.