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>
Below I made a working solution following the Angular best practices, the code is commented to help you understand it better.
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);
}
}