0

I just started to build my first AngularApp by myself. I have watched many tutorials over and over again. But I just can't figure out what I am doing wrong.

I have built apps with PHP and other languages in the past but it seems that Angular does things differently.

The problem is that I am declaring my_var at the start of my code. A couple of lines down I make an API call to get a list of items. I console log the resp and my_var values and it all looks good. When I try to use my_var outside of the API 'loop', it just turns into undefined.

I know I am doing something wrong here. I suspect I have not yet understood how variable scopes work in Angular.

Here is the component code:

rvcs;

constructor(private productService: ProductService, public configService: ConfigService, private apis: APIsService) {}

ngOnInit() {
              
        this.apis.consultarRVCs().subscribe( resp => {
            this.rvcs = resp//stores RESP values - WORKS
            console.log('Value of RESP: ',resp)//prints RESP values - WORKS
            console.log('Value of variable after storing RESP values in it: ',this.rvcs)//prints the value insde this loop/api call - WORKS
          })
        
          
        console.log('Value of variable outside of API call: ',this.rvcs);//prints undefined - Doesn't WORK

Here is the API funcition in the Service file:

consultarPopularidadPorFechaIn(id_rvc,fecha_in) {
    return this.http.get(`${this.API_URL}/consultarReservaciones/${id_rvc}/${fecha_in}`);
  }

As you can see in this picture, the last console log is being printed as undefined before the API call. This is why I suspect it has something to do with variable scopes.

enter image description here

Suraj Rao
  • 29,388
  • 11
  • 94
  • 103
  • Does this answer your question? [How to return the response from an asynchronous call](https://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-asynchronous-call) – Robby Cornelissen Jun 10 '22 at 02:47
  • I have read through all of that but still can't get it to work – Marcus Declementi Jun 10 '22 at 03:17
  • 1
    You can't call to order a pizza and then immediately start eating the pizza. You have to wait for the pizza to arrive. – Robby Cornelissen Jun 10 '22 at 03:22
  • I totally get that but how do I make it work then. Is there an alternative to subscribe? – Marcus Declementi Jun 10 '22 at 03:27
  • If you need to do something immediately upon receiving the data, you do it in the `subscribe()` block. Otherwise you assign the result to a class property (as you're doing) and use it when you need it. – Robby Cornelissen Jun 10 '22 at 03:30
  • So I can't just have an API to get list of fruits, store them for later. Then an API to get list of veggies, store them for later. To ultimately, put them together and create recipe for a smoothie – Marcus Declementi Jun 10 '22 at 03:31
  • 1
    Sure you can. You can use [`forkJoin()`](https://rxjs.dev/api/index/function/forkJoin) on your two observables, and then subscribe to the result. – Robby Cornelissen Jun 10 '22 at 03:42
  • 1
    what issue you are facing due to this undefined. as js execute the code line by line and subscription to an observable will wait untill the api response came, while during this your outer code executes and print undefined. tell us the exact issue which you are facing due to this undefined value. – Farhat Zaman Jun 10 '22 at 06:55
  • 1
    that is async subscribe would not have completed when you are logging it after the call like that, – Mark Homer Jun 10 '22 at 09:18
  • What I need is a way to get the info from my APIs without "waiting" and execute my code line by line and have it work as expected/written – Marcus Declementi Jun 11 '22 at 03:48

2 Answers2

1

The code you are posting is correct, the results from the console.log are expected.

Angular uses Observables for handle a variety of common asynchronous operations. By default, observables are lazy, if you don't subscribe to them, you will not get the response from the http call in this case.

Once you subscribe, the code within the subscribe function becomes asynchronous, meaning, it will execute later.

...
export class MyComponent implements OnInit {
  constructor(private myService: MyService) {}

  ngOnInit(): void {
    console.log('1');
  
    this.myService.getSomething().subscribe(() => console.log('2'));     

    console.log('3');
  }
}

// Output will be 1, 3, 2

You can read more about observables here: link

Andres2142
  • 2,622
  • 2
  • 14
  • 19
  • But how do I make it work. Is tehre a way to tell Angular to wait until the API info comes back and then continue with the rest of the code – Marcus Declementi Jun 10 '22 at 03:27
  • @MarcusDeclementi what logic do you need to do once you get the HTTP response? – Andres2142 Jun 10 '22 at 03:29
  • Here is what I need: Call API to get List of BracnhOffices and store it for later use. Call API to get List of Employees and store it for later use. Ultimately call an API to put those 2 pieces of data together and upload them to SQL – Marcus Declementi Jun 10 '22 at 03:35
0
async ngOnInit(): void {
  // here console.log will be called only after wait anser from service func
  this.rvcs = await this.apis.consultarRVCs().toPromise().then().catch();
  console.log('Value of variable outside of API call: ',this.rvcs);//prints undefined - Doesn't WORK
}