Encountering an error:
Error: Type 'Observable<Country[]>' is not assignable to type 'Observable'. Type 'Country[]' is missing properties like name, tld, alpha2Code, alpha3Code and more.ts(2322
The issue might be due to the endpoint returning an array with objects. Here's an example.
Here's the code that's failing to compile and producing the above error.
export class DetailsComponent implements OnInit {
country$!: Observable<Country>
countryBorders$!: Observable<Country[]>
constructor(private apiService: ApiService, private activatedRoute: ActivatedRoute){}
ngOnInit(): void {
this.activatedRoute.params.subscribe((params) => {
let countryName = params['country'];
this.country$ = this.apiService.getCountryByName(countryName)
});
};
}
The getCountryByName() method implementation:
getCountryByName(name: string) {
return this.http
.get<Country[]>(`${this.api}/name/${name}`)
}
How can I make the 'this.country$' variable hold the object data from the array returned by the HTTP request?
I tried mapping the values from the array but it did not work as expected:
ngOnInit(): void {
this.activatedRoute.params.subscribe((params) => {
let countryName = params['country'];
this.country$ = this.apiService.getCountryByName(countryName).pipe(map(([info])=>return info)
});
};
}
After making these changes, instead of the error, the template renders:
<div *ngIf="country$ | async as country">
<h1>{{country$}}</h1>
</div>
...and the h1 displays "[object Object]".
What am I doing wrong? What operators should I use to convert 'Observable<Country[]>' to 'Observable<Country' for rendering in the html template like this?
<div>
<p><strong>Native Name: </strong>{{ country$.name.nativeName }}</p>
<p><strong>Population: </strong>{{ country$.population | number : '0.0' }}</p>
<p><strong>Region: </strong>{{ country$.region }}</p>
<p><strong>Sub Region: </strong>{{ country$.subregion }}</p>
<p><strong>Capital: </strong>{{ country$.capital }}</p></div>
<div>
<p><strong>Top Level Domain: </strong>{{ country$.tld }}</p>
<p><strong>Currencies: </strong>{{ country$.currencies }}</p>
<p><strong>Languages: </strong>{{ country$.languages }}</p>
</div>
</div>
If relevant, here's the interface definition:
export interface Country {
name: Name; //---
tld: string[]; //---
cca2: string;
ccn3: string;
cca3: string;
cioc: string;
independant: Boolean
status: string;
unMember: Boolean;
currencies: Currency[]; //---
idd: Idd;
capital: string[]; //---
altSpellings: string[];
region: string;
subregion: string; //---
languages: any; //---
translations: any;
latlng: number[];
landlocked: Boolean;
borders: string[]; //---
area: number;
demonyms: any;
flag: string;
maps: Maps;
population: number; //---
gini: any;
fifa: string;
car: any;
timezones: string[];
continents: string[];
flags: Flags;
coatOfArms: COA;
startOfWeek: string;
capitalInfo: Capital;
postalCode: Postal;
}