0

I'm using this method to retrieve some data with an http.get call:

getEmpresas() {
        return this.http.get(this.empresasUrl).map(x => x.json().result[0]); 
    }

Then, I'm calling it from another component in the OnInit method:

empresas: any;
    ngOnInit() {
        // reset login status
        this.authenticationService.logout();
        this.authenticationService.getEmpresas().subscribe(res => {this.empresas = res;});

        console.log(this.empresas);

        // get return url from route parameters or default to '/'
        this.returnUrl = this.route.snapshot.queryParams['returnUrl'] || '/';
    }    

But I'm receiving "undefined" in the console output.

When I do something like this:

this.authenticationService.getEmpresas().subscribe(res => {console.log(res);});

It shows the results. Also, if I declare empresas as an array I can do something like this:

this.authenticationService.getEmpresas().subscribe(res => {this.empresas.push(res);});

And it will show me the results, but they will be inside an empty object and that's not what I want.

  • 5
    Classic async "problem"... – developer033 May 15 '17 at 21:28
  • 2
    Possible duplicate of [Angular 2 - Return data directly from an Observable](http://stackoverflow.com/questions/37867020/angular-2-return-data-directly-from-an-observable) – jonrsharpe May 15 '17 at 21:28
  • I've already tried assigning the value in the subscribe but it didn't worked. – Barbosa Thiago May 15 '17 at 21:35
  • Did you declare it as an array and then actually instantiate it as an empty array? Doing `empresas: any[]` will give you nothing. – joh04667 May 15 '17 at 22:09
  • Correction: it hasn't worked **yet**. By the time you try to log it the asynchronous process isn't complete. You need to move any work that relies on the data being available inside the callback. – jonrsharpe May 15 '17 at 22:36
  • 1
    Possible duplicate of [How do I return the response from an Observable/http/async call in angular2?](http://stackoverflow.com/questions/43055706/how-do-i-return-the-response-from-an-observable-http-async-call-in-angular2) – AT82 May 16 '17 at 06:25

2 Answers2

0
this.authenticationService.getEmpresas().subscribe(res => {this.empresas = res;});
console.log(this.empresas);

In the code above, you are executing console.log(this.empresas) immediately after calling getEmpresas() asynchronously, which means that the results have not yet been received and this.empresas is still undefined at the moment of execution of console.log.

Note that it takes some time to load the data from the service, so you should await the result of the asynchronous callback before you can log the result. In the following case, the program waits for the data or error to be received before logging it.

this.authenticationService.getEmpresas()
  .subscribe(
    res => console.log(res),
    err => console.log(err)
  );

If you are experimenting with asynchronous code, try the following.

this.authenticationService.getEmpresas().subscribe(res => {this.empresas = res;});
setTimeout(() => console.log(this.empresas), 2000);

Considering that the data is retrieved within two seconds, this code waits two seconds and then console.log the result.

Alos, if you are using something like the following in your template,

{{ empresas.name }}

change it to

{{ empresas?.name }}

to avoid errors caused by the undefined variable. Called the Angular Safe Navigation Operator (?.), it's a fluent and convenient way to guard against null and undefined values in property paths. Meaning, this will output the name only when empresas variable has some value set.

anonym
  • 4,460
  • 12
  • 45
  • 75
  • 1
    Thank you that's exactly what was happening with me. – Barbosa Thiago May 16 '17 at 15:20
  • @BarbosaThiago the `?` here is the "safe navigation operator", if you want to get more information on it. I've written up some alternatives to handling async data on my blog: http://blog.jonrshar.pe/2017/Apr/09/async-angular-data.html – jonrsharpe May 16 '17 at 17:28
0

As the code is asynchronous you do not have the result available when you log, try this:

this.authenticationService.getEmpresas()
  .subscribe(
    res => console.log(`onNext ${res}`),
    err => console.log(`onError ${err}`),
    ()  => console.log(`onCompleted`));