I am a beginner in VueJS and hope to get your help.
I'm trying to create a weather forecast application based on the OpenWeatherMap API
.
The concept is like this:
Search.vue
)Weather.vue
)I created the function with two consistent fetch calls. First get the input of the query
and return the required data from the Current Weather Data API
. After that, the function runs a second time to get the One and calls the API
obtained the first time. based on the
latitude
longitude
Everything works fine and displays fine, but I don't understand why I have an error Uncaught (in Promise) TypeError: Cannot readproperties of undefined (reading '1')
in console:
Does anyone know how to fix this error?
MySearch.vue
(Homepage) component:
<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>
MyWeather.vue
(weather results display page) component:
<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>
My router/index.js
File:
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
P粉2112735352024-03-26 13:51:34
Based on my guess (given the code and error), there may be a problem with the object you receive from the API.
The error message indicates that you are trying to read something from a specific index in the array that is not defined.
The only situation in your code that could cause this error is from the template you are reading from, for example:
{{ forecast.daily[day].dt }} {{ Math.round(forecast.daily[day].temp.day) }}
I can't tell exactly which one it is, but try double-checking the shape of the object you're working with.