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\$ Jan 26, 2022 at 15:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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