0

I have countries and cities jsons that comes from backend. And I want to make in the vuejs when I select a country in the cities select to have the cities from that country.

I got stuck here and I have no idea how to bring the cities only for that country that is selected.

Can someone please give me a little help?

Countries JSON

GET /languages/countries (list of countries)

{
    "errorCode": 0,
    "errorMessage": null,
    "contries": [
        {
            "errorCode": 0,
            "errorMessage": null,
            "rid": "1",
            "sortname": "AF",
            "name": "Afghanistan",
            "phonecode": 93,
            "links": []
        },
        {
            "errorCode": 0,
            "errorMessage": null,
            "rid": "2",
            "sortname": "AL",
            "name": "Albania",
            "phonecode": 355,
            "links": []
        },
        {
            "errorCode": 0,
            "errorMessage": null,
            "rid": "3",
            "sortname": "DZ",
            "name": "Algeria",
            "phonecode": 213,
            "links": []
        }
    ],
    "links": []
}

Cities JSON

GET /languages/countries/1 (list of cities for country with id =1)

{
  "errorCode": 0,
  "errorMessage": null,
  "cities": [
    {
      "errorCode": 0,
      "errorMessage": null,
      "rid": "33129",
      "name": "Abrud",
      "stateId": 2934,
      "links": []
    },
    {
      "errorCode": 0,
      "errorMessage": null,
      "rid": "33130",
      "name": "Aiud",
      "stateId": 2934,
      "links": []
    },
    {
      "errorCode": 0,
      "errorMessage": null,
      "rid": "33131",
      "name": "Alba Iulia",
      "stateId": 2934,
      "links": []
    }
  ],
  "links": []
}

VueJS script

export default {
    data() {
      return {
        users: {},
        countries: {},
        cities: {}
      }
    },
    created() {
      this.getUsers();
      this.getCountries();
      this.getCities();
    },
    methods: {
      getUsers() {
        this.$http.get("/user")
          .then((response) => {
            this.users = response.data.users;
          })
      },
      getCountries() {
        this.$http.get("/languages/countries")
          .then((response) => {
            this.countries = response.data.contries;
          })
      },
      getCities() {
        this.$http.get("/languages/countries/"+this.country.rid)
          .then((response) => {
            this.cities = response.data.cities;
          })
      },
    },
      components: {
            appMenu: Menu
        }
    }

HTML Selects

 <div class="form-group">
  <div class="row">
    <div class="col-6 pz-rel">
      <label class="eda-form-label" for="country">COUNTRY</label>
      <select class="eda-form-input">
        <option v-for="country in countries" :value="country.name">{{country.name}}</option>
      </select>
      <i class="ti-angle-down icons-for-select"></i>
    </div>
    <div class="col-6 pz-rel">
      <label class="eda-form-label" for="city">CITY</label>
      <select class="eda-form-input">
        <option v-for="city in cities" :value="city.name">{{city.name}}</option>
      </select>
      <i class="ti-angle-down icons-for-select"></i>
    </div>
  </div>
</div>

1 Answer 1

3

So in the first step you get all the countries.
However with the rest call for the cities you described, you cannot get all the cities for all countries at once.
So as a result I would fetch the cities for the currently selected country

EDIT the line with <option> must be changed. Currently the value will be bound to the name. So it must be changed from < ... :value="country.name" to :value="country">

<select class="eda-form-input" v-model='selectedCountry' v-on:change='getCities(selectedCountry.rid)'>
  <option v-for="country in countries" :value="country"> <!-- here -->
    {{country.name}}
  </option>
</select>

Above there is one more data variable now selectedCountry, which will hold the currently selected country. So this also must be declared in data.

data() {
  return {
    users: {},
    countries: {},
    cities: {},
    selectedCountry: null
  }
},

And give the method getCities a parameter for the country:

 getCities(countryId) {
    this.$http.get("/languages/countries/"+countryId)
      .then((response) => {
        this.cities = response.data.cities;
      })
  },
Sign up to request clarification or add additional context in comments.

13 Comments

For I don't know what reasons doesn't work. Your login it's very good, but in the console I get undefined for id in the request url : www.example.com/languages/countries/undefined
Did you also delete this line this.getCities(); in the created() lifecycle hook?
Yes I deleted. The error is Uncaught TypeError: Cannot read property 'rid' of undefined. Somehow in the getCities(countryId) the rid from selectedCountry.rid doesn't come.
That error comes after I select the country. With {{selectedCountry}} I get the right country but not the rid.
I did like u said: <select class="eda-form-input" v-model='selectedCountry' @change="getCities(selectedCountry.rid)"> <option v-for="country in countries" :value="country.name">{{country.name}}</option> </select>{{selectedCountry}}
|

Your Answer

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