4

I'm trying to extract the values from an observable, my subscription (component) code is as followed:

this.checkoutService.getDisabledDate().subscribe
(dates=>{this.formattedDate=dates}, 
(error:any)=>{console.log(error)});

In the 'dates' callback a console.log of this.formattedDate prints the correct values. However trying to access this.formattedDate outside of the subscription is undefined.

the service code:

getDisabledDate():Observable<any>{
    let headers = new Headers({'Content-Type': 'application/json' });
    let options = new RequestOptions({headers:headers});
    let userRequest={action_id:0};
    let disabledDate={};

    return this.http
        .post(this.deliveryUrl,userRequest,options)
        .map((r:Response)=>r.json())
        .catch(this.handleError);
}

I've performed the same action passing data over a queryParam using short form (), and it made no difference in this case. I seem to be overlooking what is necessary to pull out the information with this one.

I've looked at both: Angular2 HTTP using observables subscribe showing data undefined and Angular 2 return data from service is not availabe after RxJs subscribe.

Which I'm passed where their questions were answered. What am I missing?

Community
  • 1
  • 1
Chris
  • 269
  • 1
  • 3
  • 9
  • How are you trying to access this data? In your view? Did you use *ngIf like suggested in one answer, if that is the case? – AT82 Jan 30 '17 at 21:39
  • 1
    It sounds like you are trying to access the data before it's available. It's only available AFTER the observable returns a value for it. Are you sure the observable is returning, i.e. `{this.formattedDate=dates` is being called before you try to access it? That's my best guess at your issue. – VSO Jan 30 '17 at 21:48
  • This is technically a dupe of how to return a value from an asynchronous function. – Jared Smith Jan 30 '17 at 21:54
  • Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Jared Smith Jan 30 '17 at 21:56
  • Unfortunately Jared, the answer turned out to be much too simple even to be considered a duplicate of that thread. I was simply being impatient with my data. – Chris Jan 30 '17 at 22:03

1 Answers1

3

It's unclear from your question where "outside" is, but if it's after the call where you get the Observable then this is expected behavior

someMethod() {
  this.checkoutService.getDisabledDate()
  .subscribe(
    // anything here is executed sometimes later when the response from the server arrives
    dates=>{ 
      this.formattedDate=dates;
      // code that depends on the result goes here
    }, 
    (error:any)=>{console.log(error)}
  );
  // this is executed first
}

You can't get the value outside of subscribe. You can use map and return the result for the caller to subscribe, like done in getDisabledDate or you move the code to one of the callbacks.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • 1
    I understood that the asynchronous nature would mean code executed in the same method would finish before the observable. I had thought moving the subscribe to the constructor would leave time for the formattedDate to receive the values from the observable in ngOnInit. Turns out I was wrong. I moved a console.log(this.formattedDate) to a button, and behold it printed the values. – Chris Jan 30 '17 at 21:54
  • 1
    @Chris: You want to see Angular 2 Route resolves to pre-load data you need in your controller. Resolves guarantee that it's ready for you when a controller loads. See here: http://www.callibrity.com/blog/angular-2-route-resolves or here: https://blog.thoughtram.io/angular/2016/10/10/resolving-route-data-in-angular-2.html The first article is easier to read. The second is by architect-tier developers (more depth, harder to follow). – VSO Jan 30 '17 at 21:56
  • To clarify what I mean about 'outside': accessing the values of 'this.formattedDate' outside of the .subscribe(); ie. the values aren't only locally accessible to the observable, but to the scope of the receiving variable. – Chris Jan 30 '17 at 21:57
  • The question is more "when" are they available instead of "where". The part `// this is executed first` is *before* the `dates` value is available. Only `// code that depends on the result goes here` is *after* the `dates` is available. – Günter Zöchbauer Jan 30 '17 at 22:02