Code flow

I am from a Java background. I started learning Angular2 a while ago and have been working on it. In one of my projects, I ran into a situation that 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'll just register it in the console to make sure the code works fine. But it prints undefined.

This is an important part of my code.

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

      

Here is the output

number of tenders = undefined

Below is the method that 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);
    }

      

The above code snippet also has a line to print to the console. This also results in undefined. But this line is executed as soon as the variable is assigned the value obtained from the back.

I'm pretty sure my service code is getting the value from the backend. I tried printing it on my template. It prints the correct value.

Now my question is why is it printing 'undefined' to the console. These variables are assigned to values ​​correctly. From what I know, after calling the function to assign values ​​to variables, the values ​​should be available for the last parts of the code.

Please clarify this. is the code flow different from Angular2?

+3


source to share


1 answer


It prints undefined

because observables run async and therefore are not finished by the time your commands run console

. If you want to use an console.log

observable for the return value, you can move the command console

inside the function subscribe

:

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 be helpful to have a default value or, if necessary, use null checks with *ngIf

:

*ngIf="_numberOfAllTenders"

      

You can also subscribe to your template using the syntax like this:

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

//in template
{{_numberOfAllTenders | async}}

      

This method this._numberOfAllTenders

is of type Observable<number>

. And your template can subscribe to it using async

that calls subscribe

in the background and gets the value.



Since Angular 4, you can use async

inside statements *ngIf

and assign a value to a template local variable:

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

      

The main thing is that the observable does not return a value synchronously, so you need to configure other code to work with it. So if you need to use a value from one observable to call a second observable, you will need to look at the chain of observables along with flatMap

or something like this:

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

      

Or, if you need to store the value from the first observable before moving on to the second:

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

      

Hope it helps.

+3


source







All Articles