Home > Software design >  Ho do I make function wait until another async function is ready in angular?
Ho do I make function wait until another async function is ready in angular?

Time:10-08

There is some data loaded with fetch(url) and a function handleKeyboardEvent() started with @HostListener:

async ngOnInit() {
   this.loadedFromFileData = await this.getFileFromUrl('filename.wav');
}

@HostListener('document:keypress', ['$event'])
handleKeyboardEvent(event: KeyboardEvent) {
   //... wait until this.loadedFromFileData loaded
}

async getFileFromUrl(url: string) {
   let response = await fetch(url);

   let ab = await response.arrayBuffer();
   return ab;
}

How do I make handleKeyboardEvent() wait until loadedFromFileData data is loaded?

CodePudding user response:

Rather the use of Promise is being abandoned. Observables are much more convenient and offer many more possibilities. In this case, I suggest that the method returns Observable and subscribe to it, e.g. in ngOnInit() method. Thanks to the pipe() method, we can execute a series of instructions that are to happen before the end of our stream (Observable).

If we want to call an operation when we are sure that the data has already been downloaded and, for example, assigned to an object, we can perform such a function in the subscribe() method. For your case I created an example that shows how you can launch eventListener only after downloading the data.

Overall, the topic Observable is very broad and strongly related to RxJS because we use RxJS operators that allow us to modify, create, transform data, etc.

In the example on stackblitz, I added an operator that delays the download of data from the server by 5 seconds. Open the console, reload the page and press the button on the keyboard - you will see that the event does not appear in the console. First of all, the returned data will appear in the console after 5 seconds, and only then the event will react to it when you press the keys.

More info here:

CodePudding user response:

As @Pointy pointed out, you can call .then() in ngOnInit instead of await.

loadedFromFileData: ArrayBuffer;
message: string = 'no data available';
constructor() {}
ngOnInit() {
    this.getFileFromUrl(
      'filename.wav'
    ).then((res) => {
      this.loadedFromFileData = res;
    });
  }

@HostListener('document:keypress', ['$event'])
  handleKeyboardEvent(event: KeyboardEvent) {
    //... wait until this.loadedFromFileData loaded
    console.log(this.loadedFromFileData.byteLength)
    if (this.loadedFromFileData) {
      this.message = 'data loaded';
    }
  }

async getFileFromUrl(url: string) {
    let response = await fetch(url);
    console.log(response)
    let ab = await response.arrayBuffer();
    return ab;
  }

Working example on Stackblitz

  • Related