Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flow of code execution

I am from a Java background. I started learning Angular2 a while back and working on it. In one of my projects, I have come across a situation which I cannot understand.

For my pagination implementation, I am taking the number of all tenders available in the database using Angular2 observables. After getting the value, I just log it into the console just to make sure the code works fine. But it prints undefined.

This is the relevant part of my code.

this.getNumberOfAllTenders();
console.log("number of tenders = "+this._numberOfAllTenders);

Here is the output

number of tenders = undefined

following is the method which takes the number of tenders from the back end

 getNumberOfAllTenders(){
         this._tendersService.getNumberOfAllTenders().
            subscribe(

            numberOfAllTenders => this._numberOfAllTenders = numberOfAllTenders,
            error => this._error_all_numbers = error

            );
            console.log('+++++++++++++++++++ number of tenders in db = '+this._numberOfAllTenders);
    }

In above code snippet also, there is a line to print to the console. The output of that too is undefined. But that line is executed once the variable is assigned the value obtained from the back end.

I am sure that, my service code gets the value from the backend. I tried printing it on my template. It prints the correct value.

Now my question is, why it prints 'undefined' in the console. Those variables are assigned values correctly. From what I know, once the function to assign the values to variables is called, the values should be available for the latter parts of the code.

Please clarify me on this. is the flow of code execution different in Angular2?

like image 310
vigamage Avatar asked Feb 27 '26 07:02

vigamage


1 Answers

It prints undefined because observables run async and thus they aren't finished running by the time your console commands run. If you wanted to use console.log on the return value of the observable, you could move the console command to inside the subscribe function:

this._tendersService.getNumberOfAllTenders().
            subscribe(
              numberOfAllTenders => {
                 this._numberOfAllTenders = numberOfAllTenders;
                 console.log('+++++++++++++++++++ number of tenders in db = '+this._numberOfAllTenders);
              },
              error => this._error_all_numbers = error
            );

When working with variables in your component that get values from observables, it can either be good to have a default value or, if necessary, use null checks with *ngIf:

*ngIf="_numberOfAllTenders"

You can also have your template subscribe to observables directly by using a syntax like this:

//in component
this._numberOfAllTenders = this._tendersService.getNumberOfAllTenders();

//in template
{{_numberOfAllTenders | async}}

This way this._numberOfAllTenders is of type Observable<number>. And your template can subscribe to it with the async pipe, which calls subscribe in the background and retrieves the value.

Since Angular 4, you can use async inside *ngIf statements and assign the value to a local template variable:

<div *ngIf="_numberOfAllTenders | async; let myValue">{{myValue}}</div>

The main thing is an observable does not return a value synchronously and so you need to adjust your other code to work with that. So if you are needing to use a value from one observable in order to call a second observable, you would need to look at chaining the observables together with flatMap or something like that:

firstObservable()
  .flatmap(dataFromFirst => secondObservable(dataFromFirst)
  .subscribe(dataFromSecond => //do something

Or if you need to save the value from the first observable before proceeding to the second:

firstObservable()
  .flatmap(dataFromFirst => {
      this.variable = dataFromFirst;
      return secondObservable(dataFromFirst)
   })
  .subscribe(dataFromSecond => //do something

Hope this helps.

like image 152
Tyler Jennings Avatar answered Feb 28 '26 21:02

Tyler Jennings



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!