Home > Software design >  How to assign the length of an array to a number type variable in Angular 11?
How to assign the length of an array to a number type variable in Angular 11?

Time:12-08

So here is my problem, I have this going on my app.component.ts :

@Component({
selector: 'sa-app',
templateUrl: './app.component.html',
})
export class AppComponent implements OnInit, AfterViewInit {

numberEditing: number = 0;

 constructor(
private measureService: MeasureService,
) {}

ngAfterViewInit() {
 this.editing()
}

editing() {
    this.medidorService.getEditing().subscribe(editingProcess => this.numberEditing = editingProcess.length) // if I console.log(editingProcess.length) I do get the number correctly.
    console.log(this.numberEditing) // UNDEFINED
    this.test(this.numberEditing)
  }

 test(numberEditing) {
   console.log(numberEditing) // UNDEFINED
 }

And whenever I console.log(editingProcess.length) I do get the number that I want to assign to

this.numberEditing,

however, if I console.log this.numberEditing, AFTER the assignment, it is always undefined.

I tried moving the this.measureService.getEditing().subscribe(editingProcess => this.numberEditing = editingProcess.length) to inside the constructor, the result is the same. I tried making this.numberEditing into an array or an object and the object comes empty and the array doesn't work, I get:

Type 'Measure[]' is not assignable to type '[]'.
  Target allows only 0 element(s) but source may have more.

I want to use the value in numberEditing in a data chart, so I need to be able to save the value in the variable and use it after I get it, right in the component.ts , HTML is not going to be used.

I do understand that I am using an observable, so by the time I have the value on my editingProcess.length, everything else has already loaded.


But then, how do I make the variable or the function that calls the variable wait for this to happen to only then - assign the value?


The whole service was not made by me but I can access and see it, it does return something and it does return the array that I want along with the items inside it correctly, I am 100% sure the problem is on my end.

CodePudding user response:

When you subscribe to an observable, that code running is asynchronous, meaning, it will run sometime in the future, the outer console.log runs first, because is synchronous.

numberEditing = 0;

editing(): void {
  this.medidorService.getEditing().subscribe((v) => {
    this.numberEditing = v;
    console.log('inside subscribe: ', this.numberEditing)
  });
  console.log('outside subscribe', this.numberEditing)
}

The output will be:

 //outside subscribe 0
 //inside subscribe: 100

Even though the outer console log is after the subscribe, the outer console log executes first.

Whatever you need to handle after you get getEditing() do it inside the instance of subscribe, not outside.

CodePudding user response:

Thanks, I did it inside the subscribe and it worked!

Now my question would go a little deeper but I`ll look into that, I need to use that value that is stored now inside the test(number) function, somewhere else, I'll try that second answer from Hugnn to see if it works!

CodePudding user response:

This is due to async.

Try to use: async/await.

In your case, I split to getData() method to get data first:

async getData() {
       return new Promise((resolve, reject) => {
          this.medidorService.getEditing().subscribe(editingProcess => this.numberEditing = editingProcess.length)
       })}

After that, using await to fetch data:

    editing() {
        this.numberEditing = await getData();
        console.log(this.numberEditing)
        this.test(this.numberEditing)
      }

Hope that it helps you.

  • Related