【问题标题】:Vue CLI - TypeError: Cannot read properties of undefined (reading '1')Vue CLI - TypeError:无法读取未定义的属性(读取'1')
【发布时间】:2021-12-21 08:50:38
【问题描述】:

我是 VueJS 的初学者,希望能得到您的帮助。

我正在尝试基于OpenWeatherMap API 创建天气预报应用。

这个概念是这样的:

  1. 在主页上输入要输入的位置,然后单击搜索按钮。 (在我的代码中,它是一个组件Search.vue
  2. 重定向到另一个页面并显示结果 - 当前天气和未来 6 天的预报。 (组件Weather.vue

我用两个一致的 fetch 调用创建了函数。首先获取输入的输入query 并从Current Weather Data API 返回所需的数据。之后,函数根据第一次提取的latitudelongitudeOne Call API 运行第二次提取。

一切正常,显示正常,但我不明白为什么我在控制台中出现错误Uncaught (in promise) TypeError: Cannot read properties of undefined (reading '1')

有人知道如何解决此错误吗?

我的Search.vue(主页)组件:

<template>
    <div class="row">
        <div class="search-col col">
            <div class="search-box">
                <input 
                    type="text" 
                    class="search-bar" 
                    placeholder="Location" 
                    v-model="query">
                <router-link :to="{name: 'DetailedWeather', params: { query: query }}" class="btn-search">
                    <i class="fas fa-search"></i>
                </router-link>
            </div>
        </div>
    </div>
</template>

我的Weather.vue(天气结果显示页面)组件:

<template>
    <div class="row" v-if="typeof weather.main != 'undefined'">
        <div class="weather-col col">
            <div class="weather-app">
                <div class="weather-box">
                    <div class="weather-top-info">
                        <div class="clouds-level"><span class="icon"><i class="fas fa-cloud"></i></span> {{ weather.clouds.all }}%</div>
                        <div class="humidity"><span class="icon"><i class="fas fa-tint"></i></span> {{ weather.main.humidity }}%</div>
                    </div>
                    <div class="weather-main-info">
                        <div class="temp-box">
                            <div class="temp-main">{{ Math.round(weather.main.temp) }}</div>
                            <div class="temp-inner-box">
                                <div class="temp-sign">°C</div>
                                <div class="temp-max"><span class="icon"><i class="fas fa-long-arrow-alt-up"></i></span> {{ Math.round(weather.main.temp_max) }}°</div>
                                <div class="temp-min"><span class="icon"><i class="fas fa-long-arrow-alt-down"></i></span> {{ Math.round(weather.main.temp_min) }}°</div>
                            </div>
                        </div>
                        <div class="weather-desc">{{ weather.weather[0].description }}</div>
                        <div class="weather-icon">
                            <img :src="'http://openweathermap.org/img/wn/'+ weather.weather[0].icon +'@4x.png'">  
                        </div>
                    </div>
                    <div class="weather-extra-info">
                        <div>Feels like: <span>{{ Math.round(weather.main.feels_like) }}°C</span></div>
                        <div>Sunrise: <span>{{ weather.sys.sunrise }}</span></div>
                        <div>Sunset: <span>{{ weather.sys.sunset }}</span></div>
                    </div>
                </div>
            </div>
        </div>
        <div class="forecast-col col">
            <div class="row">
                <div class="forecast-item-col col"  v-for="day in forecastDays" :key="day">
                    <div class="forecast-box">
                        <div class="forecast-date">{{ forecast.daily[day].dt }}</div>
                        <div class="forecast-temp">{{ Math.round(forecast.daily[day].temp.day) }}°C</div>
                        <div class="forecast-icon"><img :src="'http://openweathermap.org/img/wn/'+ forecast.daily[day].weather[0].icon +'@2x.png'"></div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <div class="row">
        <div class="actions-col col">
            <router-link :to="{name: 'Search'}" class="btn btn-default">
                Back to search
            </router-link>
        </div>
    </div>
</template>
<script>
    export default {
        name: 'Weather',
        props: ['query'], //getting from homepage
        data() {
            return {
                api_key:'b7fe640e9a244244a6f806f3a6cbf5fc',
                url_base:'https://api.openweathermap.org/data/2.5/',
                forecastDays: 6,
                weather: {},
                forecast: {}
                
            }
        },
    methods: {
        fetchWeather(){
            // first call
            fetch(`${this.url_base}weather?q=${this.query}&units=metric&appid=${this.api_key}`)
            .then(response =>{ return response.json() }).then(this.setResults);
        },
        setResults(results){
          this.weather = results;

          // consistent second call
          fetch(`${this.url_base}onecall?lat=${results.coord.lat}&lon=${results.coord.lon}&exclude=current,minutely,hourly,alerts&units=metric&appid=${this.api_key}`)
          .then(data =>{ return data.json() }).then(this.setForecast);
        },
    
        setForecast(results){
            this.forecast = results
        },
    },
    created() {
        this.fetchWeather();
    }
</script>

我的router/index.js 文件:

import { createRouter, createWebHashHistory } from 'vue-router'
import Search from '../components/Search.vue'
import Weather from '../components/Weather.vue'

const routes = [
  {
    path: '/',
    name: 'Search',
    component: Search
  },
  {
    path: '/detailed-weather',
    name: 'DetailedWeather',
    component: Weather,
    props: true
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

【问题讨论】:

  • setForecast 是否在某处定义?你能展示一下我们的组件 Weather.vue 第 57 行的内容吗?
  • 对不起,忘了补充,我的错误:D 这是在第二次获取后重写forecast 数据结果的简单方法。在我的代码中添加methods
  • 预测值是多少?
  • 这是一个json,例如:{{ forecast.daily[0] }}{ "dt": 1636365600, "sunrise": 1636350992, "sunset": 1636384485, "moonrise": 1636367940, "moonset": 1636393920, "moon_phase": 0.14, "temp": { "day": 7.98, "min": 5.56, "max": 8.38, "night": 7.57, "eve": 8.21, "morn": 5.82 }, "feels_like": { "day": 4.71, "night": 4.56, "eve": 5.61, "morn": 2.21 }, "pressure": 1019, "humidity": 81, "dew_point": 4.84, "wind_speed": 6.54, "wind_deg": 268, "wind_gust": 12.3, "weather": [ { "id": 500, "main": "Rain", "description": "light rain", "icon": "10d" } ], "clouds": 97, "pop": 0.79, "rain": 2.2, "uvi": 0.37 }

标签: javascript vue.js fetch vue-router vue-cli


【解决方案1】:

根据我的猜测(鉴于代码和错误),您从 API 接收的对象可能存在问题。

错误消息表明您正在尝试从未定义的特定索引处的数组中读取某些内容。

您的代码中唯一可能导致此错误的是来自您正在阅读的模板,例如:

{{ forecast.daily[day].dt }}
{{ Math.round(forecast.daily[day].temp.day) }}

我无法准确判断是哪一个,但请尝试仔细检查您正在使用的对象的形状。

【讨论】:

  • 对不起,但我无法理解您提出的解决方案:/ {{ forecast.daily[day].dt }} 成功返回:1636365600。同样{{ Math.round(forecast.daily[day].temp.day) }} 返回:8。错误是一样的。你能在我的代码中告诉我我需要做什么吗?
猜你喜欢
  • 2021-08-11
  • 2022-06-28
  • 2019-10-18
  • 2020-10-09
  • 2021-12-14
  • 2020-10-03
  • 1970-01-01
  • 1970-01-01
  • 2018-06-28
相关资源
最近更新 更多