skip to Main Content

I’m trying to show the card info of South Africa as default value (before typing any country’s name into the search bar input field or chosing a specific country out of a given list) and the according country info details within the card container! In this context, I’m using the restcountries api with their country json info!
Why is it not working with ‘forEach’ and maybe you might have any ideas or suggestions how to solve it?

    beforeMount() {
        var self = this;
        var found = false;
        this.countries.forEach(function(element) {
          if(element['alpha2Code'] === 'ZA') {
            self.selectCountry(element);
            //self.push(element);
            found = true;
          }
        });      

        if(!found)
            this.selectCountry(this.countries[0]);
    
      },



html:
<main>

  <nav>
  <div id="app">
    <div class="country-search">
      <input type="text" placeholder="Search country..." autocomplete="off" v-model="search">
    </div>

    <div class="country-list" id="country-list">

      <div class="country" v-for="(country, index) in countries"  method="GET" @click="selectCountry(country)">
        <img :src="getFlagSrc(country)">
        {{ getName(country).common }}
      </div>

    </div>
  </nav>

  <section :style="{ 'background-image': url(' + selectedFlagSrc + ')' }" v-for="(country, index) in filteredCountries" @click="selectCountry(index)">

    <div class="card-container">
      <div class="card">

        <div class="card-title">
          <img :src="selectedFlagSrc.flags.png" alt="" />
        {{ selectedName.common }}
        </div>

        <div class="card-body">
          <div><strong>Code: </strong>{{ selectedCode }}</div>
          <div><strong>Capital: </strong>{{ selectedCapital }}</div>
          <div><strong>Region: </strong>{{ selectedSubregion }}</div>
          <div><strong>Language: </strong>{{ selectedLanguage }}</div>
          <div><strong>Currency: </strong>{{ selectedCurrency }}</div>
          <div><strong>Timezone: </strong>{{ selectedTimezone }}</div>
          <div><strong>Population: </strong>{{ selectedPopulation }}</div>
          <div><strong>Area: </strong>{{ selectedArea }}</div>
          <div><strong>World Bank Gini: </strong>{{ selectedGini }}</div>
          <div><strong>Lat Long: </strong><a :href="selectedLatlngUrl" target="_blank">{{ selectedLatlng }}</a></div>
</div>

      </div>
    </div>

  </section>

</main>

enter image description here

I hope to solve the issue with the default values!All around the card container on the right one should see the flag of South Africa as default bfore making any choice (respectively afterwards – the given flag of a chosen or country typed into the input field on the left in the picture below)! So far, the info concerning the chosen country haven’t been correctly transferred to the card container on the right, unfortunately ;(!

2

Answers


  1. Chosen as BEST ANSWER

    So far, I've managed to solve the background topic, the one with the card container title repetition and could also return the vast majority of the card container values (with a mix of your and my code parts), except for the currencies and languages which are definitely more challenging in the v3.1 of restcountries api and I've to think about in more detail nowArgentina's Geodata Well, default value of South Africa (beforeMount) and the geodata info for currencies and languages are still missing and to elaborate on!

    If anyone of the brain drain here had any suggestions or ideas how to cope with the remaining parts, I'd be more than grateful for any hints ;)!

    For those of you who continuously like to train their brain and solve challenging tasks, I hereby provide you with my updated code (see codepen-link below )! As I'm well aware of the fact that it is by far not perfect I'm doing my best to improve and further elaborate on it !


  2. I’ve manage to fix your code

    There are a lot of problems in your code and there are still more. You really should check it out

    HTML structrue

    You’ve put the card outside of Vue app mounting target (the div id="app" inside your html). That’s the reason why card only show {...}. Also, I have replace <div id="app"/> with <main id="app"/> because your CSS made the card overlay and cover the list.

      <main id="app">
        <nav>
          <div class="country-search">
            <input type="text" placeholder="Search country..." autocomplete="off" v-model="search">
          </div>
          <div class="country-list" id="country-list">
            <div class="country" v-for="(country, index) in filteredCountries" method="GET" @click="selectCountry(country, index)">
              <img :src="getFlagSrc(country)">
              {{ getName(country).common }}
            </div>
          </div>
        </nav>
    
        <section :style="`{background-image: url('${selectedFlagSrc}')}`">
          <div class="card-container">
            <div class="card">
    
              <div class="card-title" id="card_title" method="GET" v-if="selectedCountry" v-for="name in selectedCountry.name.common">
                <img :src="selectedFlagSrc" alt="" />
                {{ selectedCountry.name.common }}
              </div>
    
              <div class="card-body" id="card_body">
                <div><strong>Code: </strong>{{ selectedCode }}</div>
                <div><strong>Capital: </strong>{{ selectedCapital }}</div>
                <div><strong>Region: </strong>{{ selectedSubregion }}</div>
                <div><strong>Language: </strong>{{ selectedLanguage }}</div>
                <div><strong>Currency: </strong>{{ selectedCurrency }}</div>
                <div><strong>Timezone: </strong>{{ selectedTimezone }}</div>
                <div><strong>Population: </strong>{{ selectedPopulation }}</div>
                <div><strong>Area: </strong>{{ selectedArea }}</div>
                <div><strong>World Bank Gini: </strong>{{ selectedGini }}</div>
                <!--<div><strong>Lat Long: </strong><a :href="selectedLatlngUrl" target="_blank">{{ selectedLatlng }}</a></div>-->
              </div>
            </div>
          </div>
        </section>
      </main>
    

    Moreover, you didn’t close a lot of tags and misplace them. Like how you open <nav> before <div> but you close <nav> before <div>

    Computed and hook

    First, do not modify computed if you didn’t declare setter for it. That’s the reason why I deleted countries and changed it to data

    Don’t put your API call (ajax, fetch) inside computed properties. I’ve moved all logics inside computed.countries into your mounted. I also removed your filter mechanism, you’ll need to re implement it in side mounted because I don’t really understand how it worked. This is how your mounted look like

    mounted() {
        (async () => {
          const response = await fetch("https://restcountries.com/v3.1/all");
          let countries = await response.json();
          countries.sort((a, b) => a.name.common.localeCompare(b.name.common));
    
         this.countries = countries;
          // After mount, pick South Africa as default
    
          for (let [i, country] of Object.entries(this.countries)) {
            if (country["name"]["common"] === 'South Africa') {
              this.selectCountry(country, i);
    
              return;
            }
          }
    
          this.selectCountry(this.countries[0], 0);
        })();
      },
    

    I’ve also delete your beforeMount since it didn’t do anything because you declared it inside methods and you didn’t call it

    Properties

    You use some undeclared properties in HTML template like selectedFlagSrc

    Methods

    selectCountry require index to work. If index is null, the line below will fail

    self.search = self.filteredCountries[index].name.common;
    

    But you use it without providing index at mounted

    this.selectCountry(this.countries[0])
    

    There are still a lot to check. You should recheck your code before moving any further. Please be patient and coding with care.

    Since you coding your Vue application like this, I suggest take a look at Vue document to create a native Vue project. Splitting chunk to component help you debug your code easier

    This is the code after fix https://codepen.io/duckstery/pen/vYbmVmZ

    Good luck to you

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search