Данные получены из API правильно; приложение выдает TypeError с неопределенной переменной при обработке с вычисляемым - PullRequest
0 голосов
/ 06 апреля 2020

Я столкнулся с проблемами при попытке обработать данные, извлеченные из удаленного API.

Приложение работает VueJS с Vuetify, данные отформатированы с помощью компонента таблицы данных Vuetify.

Это мой code:

export default {
  data () {
    return {
      headers: [
        { text: 'City', value: 'city' },
        { text: '#Citizens', value: 'citizens' },
        { text: '#Schools', value: 'schools' },
        { text: 'Schools per Citizen', value: 'schoolsPerCitizen' },
(...)

URL-адрес API определяется как переменная на уровне приложения root.

Затем этот метод запускается, когда created() запускается:

methods: {
    loadData() {
      axios.get(citiesApiUrl)
        .then((response) => {
          console.log(response.data) // data displayed correctly
          return response.data
        })
        .catch(error => {console.error(error)})
    }
  },
  created () {
    this.loadData()
  }

Как вы заметили в комментарии, response.data отображает нужные значения.

Проблемы начинаются с этого момента:

computed: {
  stats() {
    return this.loadData().map(item => {
      item.schoolsPerCitizen = (item.schools / item.citizens).toFixed(2)
      return item
    })
  }
}

Я получаю ошибку: TypeError: Cannot read property 'map' of undefined.

Есть идеи, что не так с моим кодом?

Ответы [ 2 ]

1 голос
/ 07 апреля 2020

Проблемы

  • Когда в created вызывается loadData, обещание ax ios используется, но с возвращенными данными ничего не происходит, кроме регистрируется и возвращается в распознаватель обещаний.

  • Когда loadData вызывается в stats (вычисляется), .map отсекается от возвращаемого значения из loadData, но loadData не имеет возвращаемого значения.

  • Даже если loadData вернуло обещание топора ios, это обещание должно было бы быть использовано сначала в stats до доступа к данным ( needs .then)

  • Дизайн имеет недостатки, поскольку вычисляемый вызов будет выполнять идентичный вызов API каждый раз при пересчете, что, вероятно, не нужно.

  • Кроме того, обещание, возвращаемое stats, в любом случае не будет разрешено функцией рендеринга шаблона.

Исправление

Создание переменная для загруженных данных (назову ее mydata):

data() {
  return {
    // ...
    mydata: []
  }
}

Изменить loadData на:

loadData() {
  axios.get(citiesApiUrl).then((response) => {
    this.mydata = response.data // <--- Set the data to `mydata`
  }).catch(error => {
    console.error(error)
  })
}

Изменить stats на :

stats() {
  // This is also not designed properly, it's going to mutate `mydata`...
  // You should study Vue and learn what the purpose for computeds are before using them
  return this.mydata.map(item => {  // <-- Once `mydata` is populated, this will recalculate
    item.schoolsPerCitizen = (item.schools / item.citizens).toFixed(2)
    return item
  })
}
0 голосов
/ 06 апреля 2020

loadData не возвращает никакого значения.

loadData() {
  return axios.get(citiesApiUrl)
    .then((response) => {
      console.log(response.data) // data displayed correctly
      return response.data
    })
    .catch(error => {console.error(error)})
}
...