I've encountered a challenge that seems straightforward to most, but after investing substantial time in it, I've come to the realization that I need some assistance.
As part of my project on frontendmentor.io, I'm facing a roadblock with one specific functionality.
Let me break it down:
The initial step involves an HTTP request to retrieve data from the server and display it. I utilize the main component to fetch the data and pass it down to the child component as a list element. Upon clicking a single element, the user navigates to another component displaying more detailed information. In this new component, the process starts by extracting a parameter from the URL followed by making another request. However, instead of receiving the complete list of elements, only one element is returned from the server.
And thus continues the journey. Despite having the object correctly displayed in the console, my template remains empty, leaving me clueless about what could be causing this issue.
Data Model Example:
export interface Country {
borders: string[];
capital: string;
cca3: string;
currencies: {
[key: string]: {
name: string;
symbol: string;
}
}
flags: {
alt: string;
png: string;
svg: string;
};
languages: {
[key: string]: string;
};
name: {
common: string;
nativeName: {
[key: string]: {
common: string;
}
};
};
population: number;
region: string;
subregion: string;
tld: string;
}
Service Implementation:
export class CountriesService {
constructor(private http: HttpClient){}
getCountries(): Observable<Country[]> {
return this.http.get<Country[]>('https://restcountries.com/v3.1/independent?status=true&fields=name,nativeName,population,region,subregion,capital,tld,currencies,languages,borders,flags,cca3');
}
getSingleCountry(countryName: string): Observable<Country> {
return this.http.get<Country>('https://restcountries.com/v3.1/name/'+countryName+'?fullText=true&fields=name,nativeName,population,region,subregion,capital,tld,currencies,languages,borders,flags,cca3');
}
}
An excerpt from the component's .ts file:
export class CountryDetailComponent implements OnInit{
param!: string;
country!: Country;
constructor(
private route: ActivatedRoute,
private cs: CountriesService
) {}
ngOnInit(): void {
this.route.params.subscribe((params) => {
this.param = params['country'];
});
this.cs.getSingleCountry(this.param).subscribe(result => {
this.country = result;
console.log(this.country);
});
}
In order to display content in the template, I rely on interpolation. Notably, while the console shows the expected object structure, the actual template appears blank. This anomaly has left me scratching my head over where things may have gone awry.
I also experimented with consolidating all object elements into a single service request and maintaining a global instance of this list across the application. Unfortunately, this approach presented challenges prompting me to opt for a simpler solution instead.
EDIT: Here is a snippet of HTML component template code:
<div class="country-detail content-wrapper">
<div class="container">
<div class="button-section">
<button (click)="returnToList()">
<fa-icon [icon]="faArrow"></fa-icon> Back
</button>
</div>
<div class="details-section">
<div class="details-section__flag">
<img src="{{country.flags.svg}}" alt="">
</div>
<div class="details-section__content">
<h2>{{country.name.common}}</h2>
<div class="details-section__content--middle">
<div class="left">
<p><span class="bold">Native Name: </span>{{nativeNameArray}}</p>
<p><span class="bold">Population: </span>{{country.population}}</p>
<p><span class="bold">Region: </span>{{country.region}}</p>
<p><span class="bold">Sub Region: </span>{{country.subregion}}</p>
<p><span class="bold">Capital: </span>{{country.capital}}</p>
</div>
<div class="right">
<p><span class="bold">Top Level Domain: </span>{{country.tld}}</p>
<p><span class="bold">Currencies: </span>{{currencyArray}}</p>
<p><span class="bold">Languages: </span>{{languageArray}}</p>
</div>
</div>
<div class="details-section__content--bottom">
<p><span class="bold">Border Countries: </span><span class="border" *ngFor="let border of borderCountries" (click)="navigateToCountry(border)">{{border}} </span></p>
</div>
</div>
</div>
</div>
Please disregard any class names or extra variables/functions mentioned - they were part of various trial-and-error sessions.