Я пытаюсь загрузить видео Youtube через их API, и чтобы узнать продолжительность, мне нужно отправить второй запрос API. Проблема, с которой я сталкиваюсь, заключается в том, что иногда этот код работает, иногда он выдает
Error in render: "TypeError: Cannot read property 'contentDetails' of undefined"
Я думаю, это потому, что, когда Vue пытается получить доступ к свойству, его там нет. Если я обращаюсь к переменной (resolvedVideoData) с помощью инструмента Vue Developer при неудачной загрузке, он разрешает только ОДНО видео.
Что я делаю не так? Я вызываю запрос API в created (), поэтому модель DOM еще не загружена?
<script>
import axios from 'axios';
import moment from 'moment'
export default {
name: 'BlogGrid',
data(){
return {
videos:[],
base_url_youtube: 'http://www.youtube.com/watch?v=',
videoId: [],
resolvedVideoData: [],
}
},
watch: {
videos: function (){
var arrayLength = this.videos.length;
for (var i = 0; i < arrayLength; i++) {
this.videoId.push(this.videos[i].id.videoId);
}
this.getVideoDuration()
}
},
created() {
axios.get(`https://www.googleapis.com/youtube/v3/search?key={{YOUTUBE_API_KEY}}&channelId={{ChannelID}}A&order=date&part=snippet%20&type=video,id&maxResults=50`)
.then(response => {
this.videos = response.data.items
})
.catch(e => {
this.errors.push(e)
})
},
methods: {
getVideoDuration(){
axios.get('https://www.googleapis.com/youtube/v3/videos?id=' + this.videoId.join(', ') + '&part=contentDetails&key={{YOUTUBE_API_KEY}}')
.then(response => {
this.resolvedVideoData = response.data.items
})
.catch(e => {
this.errors.push(e)
})
}
}
}
</script>
После дополнительной проверки, если я спамлю сгенерированный URL-адрес для Google API, иногда кажется, что это возвращает одно значение, иногда он возвращает все значения.
Так как было запрошено
<section class="blog-area ptb-80">
<div class="container">
<div class="row">
<div
v-for="(item, index) in videos"
:key="item.etag"
class="col-lg-4 col-md-6"
>
<div class="single-blog-post">
<div
class="blog-image"
:href="base_url_youtube + item.id.videoId "
>
<a :href="base_url_youtube + item.id.videoId ">
<img
:src="item.snippet.thumbnails.high.url"
name="videoicon"
alt="image"
></a>
<a :href="base_url_youtube + item.id.videoId ">
<div class="overlay hidden-sm">
<div class="text">
{{ parseDuration(resolvedVideoData[index].contentDetails.duration) }}
<br>
<a :href="base_url_youtube + item.id.videoId"> <feather type="monitor" /></a>
</div>
</div>
</a>
<div class="date">
<feather type="calendar" />
{{ format_date(item.snippet.publishedAt ) }}
</div>
<div class="blog-post-content">
{{ item.snippet.title }}
</div>
</div>
</div>
</div>
</div>
</div>
</section>
с другими моими методами.
format_date(value){
if (value) {
return moment(String(value)).format('DD-MM-YYYY')
}
},
parseDuration(e){
var n = e.replace(/D|H|M/g,":").replace(/P|T|S/g,"").split(":");
if(1 == n.length)
2!=n[0].length && (n[0]="0"+n[0]),n[0]="0:"+n[0];
else
for(var r=1, l=n.length-1; l>=r;r++)
2!=n[r].length && (n[r]="0"+n[r]);
return n.join(":")
},