The API country data get loaded (see console.log()
entry and the added picture of my working desk) but no country info is shown when dragging the mouse cursor into the search bar field (should show the whole country list in a dropdown) or typing a country name into the search bar (filtering out the chosen country name)!What am I missing here in this context?
I just wanted to show the selected country data (capital, currency, language, timezone,...) from the API in the right box and its country flag as background image!
// Format a number with suffix letter
function formatNumber(labelValue) {
return Math.abs(Number(labelValue)) >= 1.0e+9
? Math.abs(Number(labelValue)) / 1.0e+9 + "B"
: Math.abs(Number(labelValue)) >= 1.0e+6
? Math.abs(Number(labelValue)) / 1.0e+6 + "M"
: Math.abs(Number(labelValue)) >= 1.0e+3
? Math.abs(Number(labelValue)) / 1.0e+3 + "K"
: Math.abs(Number(labelValue));
}
const settings = {
async: true,
crossDomain: true,
url: `https://restcountries.com/v3.1/all`,
method: 'GET',
headers: {
'X-RapidAPI-Key': 'b56451a2dcmsh7ba7285037af267p1435dajsn71561b599c58',
'X-RapidAPI-Host': 'rest-countries10.p.rapidapi.com'
}
};
$.ajax(settings).done(function (response) {
console.log(response);
});
var vm = Vue.createApp({
//var vm = new Vue({
el: '#main',
data: {
search: '',
selectedName: '',
selectedCode: '',
selectedCapital: '',
selectedLanguage: '',
selectedCurrency: '',
selectedLatlng: '',
selectedLatlngUrl: '',
selectedPopulation: '',
selectedArea: '',
selectedSubregion: '',
selectedGini: '',
selectedTimezone: '',
selectedFlagSrc: '',
},
computed: {
countries () {
var self = this;
var countries;
// Get JSON from API
$.ajax({
async: false,
//crossDomain: true,
//method:'GET',
//url: 'https://cors-anywhere.herokuapp.com/https://restcountries.com/v3.1/all',
url: `https://restcountries.com/v3.1/all`,
success: function(data){
countries = data;
}
});
// Filter search by country name in all languages
countries = countries.filter(function(value, index, array) {
return value['name'].toLowerCase().includes(self.search.toLowerCase())
|| Object.values(value['translations']).join(' ').toLowerCase().includes(self.search.toLowerCase());
});
return countries;
},
},
// Select first country in list on load
beforeMount() {
var self = this;
var found = false;
this.countries.forEach(function(element) {
if(element['alpha2Code'] === 'US') {
self.selectCountry(element);
found = true;
}
});
if(!found)
this.selectCountry(this.countries[0]);
},
methods: {
// Returns country name
getName (country) {
return (country['name']);
},
// Returns country flag URL
getFlagSrc (country) {
return (country['flag'] || 'N/A');
},
// Set country data
selectCountry (country) {
var self = this;
$('section').animate({
opacity: 0
}, 150, function() {
self.selectedName = (country['name'] || 'N/A');
self.selectedFlagSrc = self.getFlagSrc(country);
self.selectedCode = (country['alpha2Code'] || 'N/A') + ' / ' + (country['alpha3Code'] || 'N/A');
self.selectedCapital = (country['capital'] || 'N/A');
var arrayLanguage = [];
country['languages'].forEach(function(element) {
arrayLanguage.push(element['name']);
});
self.selectedLanguage = (country['languages'].length > 0) ? arrayLanguage.join(', ') : 'N/A';
var arrayCurrency = [];
country['currencies'].forEach(function(element) {
arrayCurrency.push(element['name'] + ' ' + element['symbol']);
});
self.selectedCurrency = (country['currencies'].length > 0) ? arrayCurrency.join(', ') : 'N/A';
self.selectedLatlng = (country['Latlng'].length > 0) ? ('Lat: ' + country['Latlng'][0] + ', Lng: ' + country['Latlng'][1]) : 'N/A';
self.selectedLatlngUrl = (country['Latlng'].length > 0) ? ('https://www.google.com/maps/?q=' + country['Latlng'][0] + ',' + country['Latlng'][1]) : '';
self.selectedPopulation = country['Population'] ? formatNumber(country['Population']) : 'N/A';
self.selectedArea = country['Area'] ? (formatNumber(country['Area']) + ' kmĀ²') : 'N/A';
self.selectedSubregion = (country['Subregion'] || 'N/A');
self.selectedGini = country['Gini'] ? (country['Gini'] + '%') : 'N/A';
self.selectedTimezone = (country['Timezones'].length > 0) ? country['Timezones'].join(', ') : 'N/A';
$('section').animate({
opacity: 1
});
});
},
}
});
Generally is not a good idea to make async calls in a computed property. Every time the user is typing and updating the
search
variable the computed property is being call ending will tons of request per user. You should rather make that call once and populate a variable with the results on a life cicle hook likecreated
,mounted
, etc:Once you have your list of countries you can now filter those on your computed property:
Now is up to you to create a logic on how the user select a filtered country. It could be a click on the list and the selected country is displayed. For the sake of make the example complete I created another computer property that return the first country of the filtered list and a click listener in the list that populates the search field.
Check out a working example. https://jsfiddle.net/andresabadia/n0acsj5x/5/