sonic
sonic

Reputation: 23

VueJS 3 axios can't get data

I'm newbie in VueJS 3 and I'm learning Composition API. I've made a weather website but can't get data. This is my function

setup() {
    let weather = reactive({});

    async function getData() {
        if (navigator.geolocation) {
            navigator.geolocation.getCurrentPosition(async position => {
                const API_URL = `http://api.openweathermap.org/data/2.5/weather?lat=${position.coords.latitude}&lon=${position.coords.longitude}&appid=60acb662839f9a6279f91ef167a37b9f`;
                let res = await axios.get(API_URL);
                return res.data;
            });
        }
    }
    onMounted(() => {
        getData()
            .then(data => {
                weather = data;
            })
            .catch(err => console.log(err));   
    });

    return weather;
},

It seem a asynchronous error. Please help me. Thanks in advance!

Upvotes: 2

Views: 301

Answers (3)

saber tabatabaee yazdi
saber tabatabaee yazdi

Reputation: 4959

let states = reactive({"items": ""});
let cities = reactive({"items": ""});

then

$(document.body).on("change", "#default_address_country_id", function () {
    memberNewData.default_address_country_id = this.value;

    if (this.value) {
        callStateApi(this.value)
            .then(data => {
                states.items = data;
            })
            .catch(err => {
                toast.error(err)
                console.log(err)
            })
    }
    $('#default_address_state_id').prop("disabled", false);
    console.log(states);
});

then

$(document.body).on("change", "#default_address_state_id", function () {
    memberNewData.default_address_state_id = this.value


    if (this.value) {
        callCityApi(this.value)
            .then(data => {
                cities.items = data;
            })
            .catch(err => {
                toast.error(err)
                console.log(err)
            })
    }
    $('#default_address_city_id').prop("disabled", false);
    console.log(cities);
});

then

function callStateApi(countryId) {
    const promise = axios.get('/api/state/' + countryId)
    return promise.then((response) => response.data)
}

function callCityApi(stateId) {
    const promise = axios.get('/api/city/' + stateId)
    return promise.then((response) => response.data)
}

then this as html

<div class="row mt-6">
    <div class="col-6">

        <h5 class="required ">State</h5>
        <select v-model="memberNewData.default_address_state_id"
                class="form-select form-select-transparent min-h-45px"
                id="default_address_state_id" disabled>
            <option></option>
            <option v-for="option in states.items" :value="option.id">{{ option.name }}</option>
        </select>
    </div>
    <div class="col-6">

        <h5 class="required ">City</h5>
        <select v-model="memberNewData.default_address_city_id"
                class="form-select form-select-transparent min-h-45px"
                id="default_address_city_id" disabled>
            <option></option>
            <option v-for="option in cities.items" :value="option.id">{{ option.name }}</option>
        </select>
    </div>
</div>

Upvotes: 0

Heniker
Heniker

Reputation: 679

On this line -

weather = data;

You override your weather object, so it looses reactivity.

You should add properties to the original object, not override it:

Object.assign(weather, data)

So the correct code should be:

setup() {
    const state = reactive({});

    async function fetchData() {
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(async position => {
          const API_URL = `https://api.openweathermap.org/data/2.5/weather?lat=${position.coords.latitude}&lon=${position.coords.longitude}&appid=60acb662839f9a6279f91ef167a37b9f`;
          const {data} = await axios.get(API_URL);
          state.weather = data
        });
      }
    }

    fetchData()

    return {
      state
    };
}

And in your template:

<template>
  {{state.weather}}
</template>

Upvotes: 1

Cosimo Chellini
Cosimo Chellini

Reputation: 1730

I think something like this should work

 setup() {
    let weather = reactive({});

    async function getData() {
      if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(async (position) => {
          const API_URL = `http://api.openweathermap.org/data/2.5/weather?lat=${position.coords.latitude}&lon=${position.coords.longitude}&appid=60acb662839f9a6279f91ef167a37b9f`;
          const res = await axios.get(API_URL);
          weather = res.data;
        });
      }
    }
    onMounted(() => {
      getData();
    });

    return { weather };
  },

Upvotes: 0

Related Questions