Attempting to dynamically render weather information from an API. API request is returning data that I can display in the log and on the page. However, when I attempt to display individual items in my responses arrays, the web console reports that it cannot read properties of undefined (reading ‘0’). The whole page will then stop rendering.
Code
<script>
import axios from 'axios'
export default{
data() {
return {
weather: []
};
},
async created(){
try{
const response = await axios.get('apilinkredacted');
this.weather = response.data.daily;
console.log(this.weather)
} catch (error) {
console.error(error);
}
}
}
</script>
<template>
<main>
<div v-for="n in 4" class="text-cliPurple border-t border-windowOutline pb-2 pl-2">
<!-- weather.daily.temperature_2m_max[n-1] -->
<p class="underline">{{ weather.time[n-1] }}</p>
<div class="grid grid-cols-2">
<div class="">
<pre>
/
.-.
― ( ) ―
`-’
/
</pre>
</div>
<div class="text-left">
<p><span class="text-cliOrange">Temp:</span> {{ weather.temperature_2m_max[n-1] }} C</p>
<p><span class="text-titleColor">Rain Chance:</span> {{ weather.precipitation_probability_max[n-1] }}%</p>
<p><span class="text-userColor">Rain Amount:</span> {{ weather.rain_sum[n-1] }}mm</p>
<p><span class="text-cliRed">UV:</span> {{ weather.uv_index_max[n-1] }}</p>
</div>
</div>
</div>
</main>
</template>
JSON response
{
"latitude": -35.25,
"longitude": 149.125,
"generationtime_ms": 0.06699562072753906,
"utc_offset_seconds": 36000,
"timezone": "Australia/Sydney",
"timezone_abbreviation": "AEST",
"elevation": 568,
"daily_units": {
"time": "iso8601",
"temperature_2m_max": "°C",
"apparent_temperature_max": "°C",
"uv_index_max": "",
"rain_sum": "mm",
"precipitation_probability_max": "%"
},
"daily": {
"time": [
"2024-05-09",
"2024-05-10",
"2024-05-11",
"2024-05-12",
"2024-05-13",
"2024-05-14",
"2024-05-15"
],
"temperature_2m_max": [
16.5,
14.9,
13.1,
13.4,
17.5,
15.9,
14.7
],
"apparent_temperature_max": [
14.4,
13.2,
11.4,
11.1,
16,
14.6,
13.8
],
"uv_index_max": [
1.95,
2.55,
0.6,
3.9,
4.2,
3.95,
3.65
],
"rain_sum": [
0,
5.1,
26.5,
3.7,
0,
0,
0
],
"precipitation_probability_max": [
52,
74,
90,
37,
0,
0,
3
]
}
}
I initially thought it was because the item wasnt an array but when I used console.log(this.weather.time[0]) I get the correct data printed in the web console. If I don’t specify the specific items, I can render the whole response multiple times but when I add the specifics and reload the entire page goes blank.
Additionally, when I the Get request to store the individual array this.weather = response.data.daily.time;
I can address the individual items by using weather[0]
and it displays no problem.
2
Answers
Daniel was correct, page was rendering before the get request had been fulfilled. Changed the weather type to {} and added this around the v-for:
Now it waits until the request has data to attempt rendering the component.
You are trying to access data that does not yet exist.
You have two options
use ? (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining)
{{time?.time[n-1] }}
2), introduce a v-if in your code
On the other hand, you are making some mistakes.
The first is that the weather data type is a [], but then you pass a {} when you set it in the created method.
The second is that you should avoid accessing data by index