0
\$\begingroup\$

I am making a website where you can search through all the countries in the world. Once you have found a country you want more detail about you should be able to click and view a detailed page with more info.

I am having trouble updating the countries that are currently shown with the user's restrictions. I want to add an eventListener to every active card to be able to open the detail page for that specific country. Is there a way to do it without an interval function checking every other second? I have a feeling this is not the correct way.

Here is the interval function:

function updateActiveCards(){
  activeCards = Array.from(document.querySelectorAll('.search-result-card'));
}

setInterval(updateActiveCards, 1000);

Here is an example of how a search result would look enter image description here

All the added cards get a class of 'search-result-card' and they are added by this code:

async function loadCountriesByName(name){
  const respone = await fetch('https://restcountries.com/v2/name/' + name);
  const data = await respone.json();
  data.map(element => {
    addCountry(element);
  });
}

async function loadAllCountries(){
  const response = await fetch('https://restcountries.com/v2/all');
  const data = await response.json();
  data.map(element => {
    addCountry(element);
  });
}

searchBar.addEventListener('input', () => {
  const currentValue =  searchBar.value;
  if(currentValue == ''){
    results.innerHTML = '';
    loadAllCountries();
  } else {
    results.innerHTML = '';
    loadCountriesByName(currentValue);  
  }
});

function addCountry(CountryData){
  const newCard = document.createElement('div');
  newCard.classList.add('search-result-card');
  newCard.innerHTML = `
    <div class="country-img">
      <img src="${CountryData.flag}" alt="">
    </div>
    <div class="country-info">
      <h2>${CountryData.name}</h2>
      <h3>Population: <span>81,770,900</span></h3>
      <h3>Region: <span>Europe</span></h3>
      <h3>Capital: <span>Berlin</span></h3>
    </div>
  `
  results.append(newCard);
}

loadAllCountries()

Thanks in advance!

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Disclaimer

This is my response based on the following information:

  • At the start, all countries with basic details shall be listed.
  • A user can type some string and the countries displayed will be reduced to only those matching the filter.
  • At anytime, before or after searching, a country "card" can be clicked, forcing the page to update with more detailed information.

Solution

I have created a small repo using some of your code examples and expanding on them as needed. I did not worry about styling or populating information on the page as the concern was regarding the click event.

This line has what I believe you are looking for regarding an eventListener.

newCard.onclick = cardClickHandler

Once you have your element, you can attach a function as a handler for any of its events.

Code Review

As this is the codereview stackexchange, I feel obliged to pass along a few comments on your approach.

As a common courtesy to API providers (internal or external) try to make as few requests as needed to accomplish your goals. This block of code makes a request to the all countries end point every time the search is cleared, which I feel is not necessary in this case. You would be safe to assume that this data is not going to change during a user's visit to this page. See these lines of code for an alternative.

  if(currentValue == ''){
    results.innerHTML = '';
    loadAllCountries();
  } else {

I'm not sure what the purpose of this assignment is (school, work, hobby, etc.), but you should consider approaching problems like this with a library (react, angular, vue) designed for helping with some of the ideas you are trying to implement (components, event handling)

Hopefully this helps.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks a lot for taking the time to look into this. I am teaching myself how to code and I wanted to do a bigger project before starting with react or any other libraries. I fixed all the issues you stated above and it works much better now. \$\endgroup\$ Commented Jan 26, 2022 at 15:27

Not the answer you're looking for? Browse other questions tagged or ask your own question.