Cannot assess the http post response data from outside of the .subscribe

I am using a http request to get a url from a server and it returns correct data as the response. after i set the data to a variable i cannot access the variable data from other method.

this is my code

public  urlcheck:any;
check:String;

constructor(public http: Http) {

   //what i want to do is something like this, it works when i do like this.
   //urlcheck = "http://10.0.2.2/mysite/";


   this.urlcheck = this.http.get('http://localhost/website/index.php/Admin/getpublicip');
   this.urlcheck.subscribe(data => {
      //console output is  ('my data: http://10.0.2.2/mysite')
      console.log('my data: ', data["_body"]);
      this.check = data["_body"];
      //console output is  ('my url: http://10.0.2.2/mysite')
      console.log("check url"+this.check);

   })
//console output is ("check url  undefined")
console.log("check url"+this.check);
}

what am i missing?

If you start by printing the content of this.urlcheck properly, that will probably help:
console.log(“Check url”, this.urlcheck);

But its most likely since you’re reassigning the same variable for the response and the body. Since you subscribe for a response it will go past your subscribe and simply console log out a promise object that youve assigned for the response.

thanks for the reply.i have update the question. now it says “undefined”

As stated in my first reply, since you’re subscribing to this.http.get, this.urlcheck will simply be set to a promise.

Are you getting a response? Inside the subscribe?
I believe you’re possibly confused of the order of things here:

  1. this.urlcheck = this.http.get(‘http://localhost/website/index.php/Admin/getpublicip’);
    this.urlcheck.subscribe(data => {

    this.check = data["_body"];
    3) console.log(“check url”+this.check);

})
2) console.log(“check url”+this.check);

1 = Subscribing to the get request.
2 = Since you wont go inside the subscribe immediately, you will simply go past it and print whatever this.urlcheck is set to (I would think it would be a promise obj)
3 = Getting the response form the http request.

You have to remember things are async here.

so what should i change in order to archive my needs?

Forget everything you think you know so far and start completely over reading this.

What’s happening here is the subscription is asynchronous. The very last console.log is running before the inner contents of the subscription run, hence why it’s undefined.

Read about RXJS and promises - they are hard to understand at first but they will help you tremendously.

Here are three examples:

import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
import { Subject } from 'rxjs';
import { map, take } from 'rxjs/operators';
import { HttpClient } from '@angular/common/http';

@Component({
  selector: 'app-view',
  templateUrl: './customer-overview.page.html',
  styleUrls: ['./customer-overview.page.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush
})
export class CustomerOverviewPage implements OnInit {

  private readonly apiUrl = "http://10.0.2.2/mysite/";
  private readonly $myHttpCall = this.httpClient.get(this.apiUrl).pipe(
    map(response => response['_body'])
  );

  private readonly $option3 = new Subject<any>();
  private readonly option3Subscription = this.$option3.pipe(take(1)).subscribe(response => {
    console.log('Response3', response)
  })

  constructor(private readonly httpClient: HttpClient) { }

  async ngOnInit() {
    // Option 1. Convert Observable to Promise
    const response1 = await this.$myHttpCall.pipe(take(1)).toPromise();
    console.log('Response1', response1);

    // Option 2. Subscribe to Observable and do something upon response
    this.$myHttpCall.pipe(
      take(1)
    ).subscribe(response => {
      console.log('Response2', response)
    });

    // Option 3. Subscribe, then set a Subject to the value which will log the response because of the other subscription
    this.$myHttpCall.pipe(
      take(1)
    ).subscribe(response => {
      this.$option3.next(response)
    });
  }

  public async onButtonClick() {
    console.log('Bonus', await this.$option3.pipe(take(1)).toPromise())
  }

}

1 Like

Don’t poke around in other classes’ internals like this. Leading underscores mean “hands off”.

1 Like

@rapropos, I was just using the example response field the OP used to make it easier to understand and apply. In my own work, everything is strongly typed/mapped and in pascal case.

That is an interesting note though, the api the OP’s using is returning what are supposed to be private fields.

1 Like

The way I read it, OP was just copypastaing something from some outdated garbage “tutorial” blog. That’s why I suggested upthread to just forget trying to fix the code that is there and start over with HttpClient instead of the obsoleted @angular/http. We used to see code fragments like that here all the time.

1 Like

@joelmeaders Thankyou!