0

When I awaited an array of items from the API it successfully received and assigned to the variable.

async ngOnInit(): Promise<void> {
    this.items = await this.apiService.getItems().toPromise();
}

But when I try to call it from another function, which for example, assigned to click event in the template, it received empty.

getSomeValue() {
    var value = this.items;
}

this.items is an empty array at that time. Why this happens and how to work around it?

Yaroslav
  • 358
  • 3
  • 14
  • In that question guy subscribed to his API, I instead awaited it and believe that this data will be available after the ngOnInit hook finished. In my example getSomeValue() called from the template when the user clicks on the button, at this time ngOnInit already finished. So I don't understand why this data available right after the awaiting but not in another function which called a long time after. – Yaroslav Feb 28 '21 at 14:59
  • It is possible to mark a method as `async` and still call it without using `await` and this is what is happening for you. Internally angular isn't using `await`, so code execution is not waiting for the results of your async api call. [StackBlitz sample](https://stackblitz.com/edit/so-66410244?file=src/app/app.component.ts) | [Mozilla Docs for async functions](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function#description) – BizzyBob Feb 28 '21 at 17:35

1 Answers1

0

Looks like you are firing the click event before we get the data from the service.

A workaround could be to add a disabled attribute to the button

<button [disabled]="!items">Get some value</button>

or completely hide it unless and until we do not have any data.

<button *ngIf="items">Get some value</button>

EDIT:

Per your comment, awaits in an async function halts execution of the following statements in that function itself and not halts execution of other hooks.

https://stackoverflow.com/a/42833744/2078685 could help you understand better

Per the below example, You will see

Hi
lo
1

and not what you might be thinking

async function foo() {
      console.log("hi");
      return 1; 
    }
    
    async function bar() {
      const result = await foo();
      console.log(result);
    }
    
    bar();
    console.log("lo"); 
Saksham
  • 9,037
  • 7
  • 45
  • 73