0

Good morning all
I can't use the result of this request(i want use it in a local variable)
here is my code that i put in ngOnInit

  appli:any=[];
  ngOnInit() {

    this.http.get<any>(this.url).subscribe(data => {
      console.log(data) //returns data
      for (let item of data) {
        this.appli.push(item)
      }
      console.log(this.appli) //returns data
    });
    console.log(this.appli) //returns data
    console.log(this.appli[0]) //returns undefined
    console.log(this.appli.length)// returns 0

  }


jakehard
  • 67
  • 7

3 Answers3

1

Http calls are async so the statements outside the block will be executed first then the ones inside the http block when the data arrives

The other way to wait for data is to use async-await

Oninit(){
 getAsyncData();
}

 async getAsyncData() {
    this.asyncResult = await this.http.get<any>(this.url).toPromise();
    // execution of this statement will wait until promise is resolved..');
    // now you can do anything with your data i.e stored in this.asyncResult and it will get executed after the data arrives 
  }

For more clarification and details you can check the following link as well

https://medium.com/@balramchavan/using-async-await-feature-in-angular-587dd56fdc77

Shlok Nangia
  • 2,355
  • 3
  • 16
  • 24
0

It is default behaviour when you work with observables.

console.log(this.appli[0]) //returns undefined
console.log(this.appli.length)// returns 0

Above lines are returning undefined and 0 because these are outside the scope of Subscribe function and will execute even before receiving API response. this.http.get returns an observable and doesn't stop the code execution.

I am pretty sure that even line:

console.log(this.appli) //returns data

will run before API returns a response.

If you put above console statements inside Subscribe function, these will print correct outputs.

Rohit Garg
  • 493
  • 2
  • 12
0

Response from HTTP client is asynchronous. Please see here for more info on it.

It means all logic depending on the HTTP response should be moved inside the subscribe. Sidenote, <any> could be removed here, it doesn't define any specific object model. And it is always better to handle HTTP calls from a service in case multiple components require the data from this.url. It is also good practice to handle the error.

The following should work

ngOnInit() {
  this.http.get<any>(this.url).subscribe(
    data => {
      console.log(data);
      for (let item of data) {
        this.appli.push(item);
      }
      console.log(this.appli);

      console.log(this.appli[0]);
      console.log(this.appli.length);
    },
    error => {
      // handle error
    }
  );
}

If you wish to iterate the array in the template, you could try the following

Controller

app: any;

ngOnInit() {
  this.http.get(this.url).subscribe(
    data => { this.app = data; },
    error => { // handle error }
  );
}

Template

<ng-container *ngIf="app">
  <div *ngFor="let item of app">
    {{ item }}
  </div>
</ng-container>
ruth
  • 29,535
  • 4
  • 30
  • 57