javascriptangularasync-await

How to use async function to await user input from onClick?


I am trying to fetch data from an external api and I use async and await. I want to wait for user input from an onClick function and then to pass the url to an async function and to get the data in json format form that url. OnClick function is working:

onClick(){
   this.data=(<HTMLInputElement>document.getElementById('data')).value;
    
   return this.url='https://api.url.info/feed/'+this.data
}

When I use console.log(data2) undefined an the next error: Failed to load resource: the server responded with a status of 404 (Not Found)

async getData(){
    var data2=this.url;
    const response=await fetch(this.url);
    this.data=await response.json();
}

ngOnInit(){
    this.getData();
}

HTML

<input type="text" id="data"  value=""/>
<button type="button" (click)="onClick()" id="btn">Search</button>


Solution

  • Below I made a working solution following the Angular best practices, the code is commented to help you understand it better.

    Demo

    Template

    <input #yourData id="data" type="text" id="input"  value="" />
    <button type="button" (click)="onClick()" id="btn">Search</button>
    

    Component

    import { Component, OnInit, ViewChild, ElementRef } from "@angular/core";
    import { HttpClient } from "@angular/common/http";
    
    @Component({ ... })
    export class YourComponent implements OnInit {
      data: any; // The api response is going to be stored here
      baseUrl: string = 'https://api.url.info/feed/';
    
      // You need to import the HttpClientModule in your module (in the AppModule is ideal)
      // Make sure to import it only once.
      constructor(private http: HttpClient) { }
    
      // One of the proper ways to access
      // Documentation: https://angular.io/api/core/ViewChild
      @ViewChild("yourData", { static: true })
      yourTemplateElement: ElementRef<HTMLInputElement>;
    
      // Use ngOnInit if the static option is set to true, use ngAfterViewInit otherwise
      async ngOnInit() {
        this.data = await this.getData(this.baseUrl);
      }
    
      getData(url: string): any {
        // Use the http client service to make http calls.
        // By default it returns an observable but since you want to use
        // the async/await keywords, we need to convert it into a promise
        return this.http.get(url).toPromise();
      }
    
      async onClick() {
        const urlSegment = this.yourTemplateElement.nativeElement.value;
        this.data = await this.getData(this.baseUrl + urlSegment);
      }
    }